Modular services with OpenJDK Jigsaw and Guice

Tim Boudreau niftiness at gmail.com
Mon Jul 9 07:00:32 PDT 2012


I think I can now describe how to do this with Guice - it requires a small
dirty trick - register a listener which "hears" all injections, and puts
the type being injected into a ThreadLocal;  then bind a provider which
looks in the ThreadLocal to see what to inject.  But you will still need a
way to iterate the list of types which should be bound, to tell Guice about
them at startup.  You might be able to write a Key subclass that allows
them to be bound without actually loading the classes, though.

Guice 3.0's API probably has enough meat on it to do fancier things.  It is
true that Guice generally wants to know explicitly what bindings are on VM
startup - lately the way I deal with this for complex registration is to
write an annotation processor which generates some sort of file with a list
of bindings, and then read that at runtime.  I've also used Lookup as a
layer underneath Guice - generally with Guice, either an interface has to
specify its implementation with @ImplementedBy, or there must be a Guice
module which knows about both the interface and the implementation class
and glues them together.  So true service "discovery" is out-of-scope for
Guice - and Lookup is very handy for a bootstrapping layer which does that,
underneath Guice.

I don't think lazy loading or late binding was ever something Guice was
designed for - its target is server side applications where, in a
deployment scenario, it's more important that the application fail fast
(i.e. unsatisfied bindings are detected at startup) than that the
application start up fast.  So generally, you imperatively *tell* Guice
about bindings - it is very magic-free.  I think this is the correct target
for Guice - it is simply solving a different problem for a different kind
of application than Lookup is.

FYI, if you
hg clone http://timboudreau.com/code/useful
and look in the guicey/guicey project, you will find an implementation of a
Guice Scope over Lookup;  you could probably do whatever you want with how
the Lookup it uses gets constructed.  However, something still needs to
bind those types in that scope (see AbstractScope.bindTypes()) - in
practice typically there is some well-known object (application main class)
which I just annotate with the list of additional types to bind in the
appropriate scope (in fact, weirdly, I end up injecting a Scope object).

-Tim

On Mon, Jul 9, 2012 at 7:49 AM, Jaroslav Tulach
<jaroslav.tulach at oracle.com>wrote:

> Dne Pá 6. července 2012 18:43:08, Paul Sandoz napsal(a):
> > Something for the weekend:
> >
> >
> http://earthly-powers.blogspot.fr/2012/07/modular-services-with-openjdk-jigs
> > aw.html
>
> Interesting. I was playing with something similar, but with Spring:
> http://wiki.apidesign.org/wiki/LookupAndSpring
> Translation notes:
> - Lookup.getDefault() means something like ServiceLoader.load(all_types)
> - @ServiceProvider is "provides service"
>
> I was trying to do this with Guice as well, but it does not work well.
> Guice
> would like to know all registered services before its "module" is
> constructed
> and we were seeking for a lazy binding. However we have not managed to
> convince Guice to call us back, when a particular type is needed. We gave
> up.
>
> -jt
>
>


-- 
http://timboudreau.com



More information about the jigsaw-dev mailing list