services, take 1

Alan Bateman Alan.Bateman at oracle.com
Fri Dec 16 07:54:00 PST 2011


One of the areas that I've started to look into is how services might be 
implemented at installation and runtime. Note that I'm not talking about 
dynamic services and registration but rather a simple means to install 
service providers as modules so that they can be found at runtime via 
the ServiceLoader API. As the subject line suggests, I'm sure that we 
will go through several iterations on this topic.

To get things started, I've created a first implementation [1], intended 
for discussion rather than code review. With this implementation then a 
module that declares a dependency on a service (specified by interface 
or abstract class name, not versioned) is linked with the modules that 
declare that they provide the service. At runtime the ServiceLoader API 
can be used to load the implementations of the service.

A couple of notes/discussion points:

1. The resolver changes are very simple for now. When a module requires 
a service then the names of the modules that provide that service are 
pushed onto the choice stack for the purposes of module selection. 
Resolution fails if there aren't any modules providing the service and 
the dependency is not optional.

For now permits is ignored. If it were to apply then it would likely act 
as a filter. Another issue that isn't addressed is the case where 
several versions of a module are installed and some, but not all, 
provide the service. I've also ignored remote repositories for now but 
one could envisage modules that provide the service being candidates to 
download and install.

2. The changes to the linker are also very simple. Contexts that provide 
a service becomes service suppliers to modules that require the service. 
The set of  service suppliers is separate to the supplying contexts (for 
visibility reasons). The additional maps are stored in the configuration 
to make them available at runtime. There will be a few other changes 
needed here once we get back to the run-time modulepath support.

3.  ServiceLoader is updated so that when we are in module mode it goes 
to the module class loader to get the service implementation classes 
that are in both the local and remote contexts supplying services. In 
legacy mode, or where class loaders other than module class loaders are 
used, then it continues to look for service configuration files.

There are many discussion points around ServiceLoader. The main one that 
I've been thinking about is the loadInstalled method and the other load 
methods when presented with the system class loader. In module modes the 
system class loader is the module loader that loads the class with the 
entry point. The approach that I've taken for now is to use the class 
loader of the class of the calling frame for cases where loadInstalled 
or load is called with the system class loader. This eliminates 
surprises. ServiceLoader also defines a load method that uses the 
context class loader and that requires further consideration as to how 
it might work in module mode. We will need to get more experience using 
ServiceLoader in module mode before deciding whether additional 
APIs/changes may be required. We'll also need to see how ResourceBundle 
will work in module mode.

4. In the current Jigsaw build the module-info classes are generated in 
the build so I've modified the class analyzer to generate the "requires 
service" and "provides service" declarations based on the dynamic config 
file that we have checked into the repository, and the entries in the 
existing service configuration files.

5. To aid migration the jar command "I" module is updated to add the 
provides attribute to the generated module-info class when service 
configuration files are present in the JAR file.

That's about it for now. As I said above, this is very much a first 
implementation and much clean-up and discussion is required. My 
repository isn't quite up to date with Mandy/Jon's work on views 
although views providing service is working. I hope to merge/sync up soon.

-Alan.

[1] http://cr.openjdk.java.net/~alanb/jigsaw-services/webrev/





More information about the jigsaw-dev mailing list