Migrating to uses from an existing module system

Alan Bateman Alan.Bateman at oracle.com
Wed Nov 30 10:11:07 UTC 2016


On 29/11/2016 22:45, Thomas Watson wrote:

> I have a usecase where I am attempting to map an existing module system's
> class loaders to JPMS modules by using the Layer API.  In this case the
> existing module system is OSGi.  I have run into an issue when an existing
> OSGi bundle contains code that uses the ServiceLoader.  For the sake of
> discussion the existing code could look like this:
>
>          ServiceLoader<PrintServiceLookup> sl =
> ServiceLoader.load(PrintServiceLookup.class);
>          System.out.println(sl.findFirst().orElseGet(() -> {return
> null;}));
>
> Without mapping OSGi to JPMS modules this code works fine.
but only if you resolve the modules that provide implementations of 
PrintServiceLookup. The platform modules may provide one or more 
implementations of PrintServiceLookup but there may be others that the 
above consumer may wish to select.

I guess I can't quite tell if you are doing service binding 
(resolveRequiresAndUses) or not. Even so, I assume the generated module 
doesn't declare any `uses`, hence there won't be any any service 
consumers (beyond what the platform modules might provide).

>   This is
> because the code ends up being loaded by an unnamed module for which JPMS
> assumes is allowed to use any service through the ServiceLoader.  But once
> I map the OSGi bundle class loader to a JPMS module the code above fails
> to work with an exception:
>
> java.util.ServiceConfigurationError: javax.print.PrintServiceLookup:
> module test.service.loader does not declare `uses`
>
> Is there any way around this?  I know there is an addUses method, and I
> also know that I can generate ModuleDescriptors for my Layer that specify
> a proper uses requirement.  But that would require a code scan to discover
> all possible calls to the ServiceLoader in order to declare the uses.
Existing code can been coerced into an automatic module and can use any 
service provider in modules that are resolved by other means. However, 
in the above then it looks like existing code has been coerced into a 
"normal" module and is missing its `uses` declaration. This means it has 
to use addUses at run time (the check that you run into is specifically 
there to ensure that consumer modules declare the service types that 
they use, it shouldn't be necessary to have to list the service provider 
modules explicitly via --add-modules or equivalent).

-Alan


More information about the jigsaw-dev mailing list