Order of Services
Jaroslav Tulach
jaroslav.tulach at oracle.com
Mon Feb 27 01:13:32 PST 2012
>## Alan wrote on 25. 2. 2012 18:17:07 ##<
> On 23/02/2012 15:38, Jaroslav Tulach wrote:
> >> ## Alan wrote on 23. 2. 2012 13:16:14 ##<
> >> service. Clearly if someone installs another module that also provides a
> >> SelectorProvider implementation then it's like installing into the
> >> extensions directory in the current world; one will be chosen and
> >> there's a way to override it. In the implementation then the order is
> >> stable and doesn't change between runs.
> >
> > NetBeans solves problem this by positioning. The
> > http://bits.netbeans.org/dev/javadoc/org-openide-util-
> > lookup/org/openide/util/lookup/ServiceProvider.html
> > annotation (that generates the META-INF/services/xyz file) has attribute
> > position.
> >
> > ServiceLoader could be honor such position indicator and sort services
> > accordingly.
>
> I'm curious as to your experiences with this approach. In particular has
> it been problematic for cases where the order needs to configured by the
> user of the service providers?
I'd describe the NetBeans approach as "convention over configuration". The
individual library modules contribute their registrations, but the final
application can use "branding" and change almost everything.
Usually the defaults are OK and then it is enough to include a module in and
things work. If there are problems, the application (which knows about all
modules it includes) can orchestrate the registrations.
The @ServiceProvider annotation
http://bits.netbeans.org/dev/javadoc/org-openide-util-
lookup/org/openide/util/lookup/ServiceProvider.html
has supersedes attribute. It can be used to hide services provided by library
modules and replace them with more sophisticated ones.
It seems that the position attribute with ability to supersede some
implementations is enough for everyone building their applications on top of
the NetBeans Platform.
> Also I wonder about cases where there are
> multiple applications are loading the service providers and the order
> needs to be different.
That would be achieved by different "branding" in different applications built
on top of the NetBeans platform.
> In the JDK we have examples such as the
> java.security file that list the security providers and the preference
> order. There are other examples where the preference order is determine
> by system properties. We don't have a general mechanism for ordering and
> might be a bit beyond the scope of getting services deployed as modules
> (still interesting to hear your experiences).
Yes, this may get complicated. The tentative goal might be to "change the
order of services without writing any Java code".
NetBeans handles that with "branding" which is yet another level on top of
L10N. Each application can contribute fragments to existing modules and re-
brand any resource found in that module. ResourceBundle[1] then loads the
branded file rather than the default. Possibly the application might redefine
META-INF/services/xyz file of any library module it is using[2].
> >> As I said, I think ServiceLoader has to change.
> >> The load(Class) method is specified to use the
> >> threadContextClassLoader but what if that has been set to null or
> >> ClassLoader.getSystemClassLoader
> >
> > NetBeans solves[1] this problem by registering special Thread.cCL that
> > can see classes from all enabled modules in the running VM. Thus by
> > default using ServiceLoader.load finds all services provided by all
> > enabled modules.
>
> Sure, but my point was getting code that has it to null or
> ClassLoader.getSystemClassLoader. In the current prototype the latter is
> the module loader of the module for the main class and so may not be the
> right loader. As DML suggested, it would require existing code to change
> but how we handle such cases it still something that needs further
> consideration in my view.
I was not trying to advocate usage of threadContextClassLoader. Rather I
wanted to say that it makes sense for ServiceLoader to see all services from
all enabled modules in the running JVM by default.
-jt
[1] We use special factory class that understands branding instead of
ResourceBundle:
http://bits.netbeans.org/dev/javadoc/org-openide-
util/org/openide/util/NbBundle.html
[2] We don't use rebranding of META-INF/services/xyz files in NetBeans right
now, but we do use this technique in other similar situations
More information about the jigsaw-dev
mailing list