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