Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [sisu-users] Problem with the Sisu Extender

On 4 Sep 2013, at 14:52, gian.maria.romanato@xxxxxxxxxxxx wrote:
Hello,

I'm trying to use the sisu extender in an OSGi application, but I it does not seem to work as expected. I am using M5.

Here is my configuration. I have two bundles, B1 and B2, where B2 depends on B1. The Sisu extender is started before B1 and B2.

B1 bootstraps the Injector with a custom module "someModule" as follows:
injector = Guice.createInjector(new WireModule(someModule, new SpaceModule(new BundleClassSpace(FrameworkUtil.getBundle(getClass())))));
B2 declares an additional module via META-INF/services/com.google.inject.Module

In debug I see that SisuActivator is starting and that is starts tracking bundles and services.
I also stepped into the code that instantiates the module declared by B2, creates a new Injector out of it and registers the Injector in the DefaultBeanLocator.
The OSGi console also shows that the SisuActivator has registered a BundleInjector service on behalf of B2.

Now, if I write code in B2 that uses the same injector instance that was created by B1, I can succesfully instantiate objects and have their fields injected with classes that are bound by "someModule".
But if I try to do the same with objects that would require injections that are bound by the module declared in B2, Guice complaints that no implementation could be found.

If the objects that you are trying to instantiate were defined in B2 then you should use their defining injector as this would contain both their bindings and the necessary bindings to fetch the required dependencies from B1's injector. Think of injectors as loosely-coupled sources of bindings, with any missing (local) dependencies routed through the BeanLocator. Also how are you using the injector, are you relying on the getInstance method? The WireModule uses the Guice SPI to analyze declared bindings for missing dependencies, so if you use the getInstance method programatically then this won't be observed by the WireModule and it won't add a binding that instead delegates to the BeanLocator.

Alternatively you could always use the BeanLocator to programatically query and instantiate objects:

    beanLocator.locate( Key.get( myType ) ).iterator().next().getValue()

This could be hidden behind a utility method to limit dependency of your code to Sisu-specific types.

What am I missing? I believe I should tell the Injector to use the bean locator created by SisuActivator. How can I do that?

To use a given locator in a new injector, add an instance binding to it when defining the bindings:

    bind( DefaultBeanLocator.class ).toInstance( locator );

This will also auto-register the injector with the locator, then you just need to wrap a WireModule around your modules to add any missing links.

BTW, is your code available somewhere?  I'm always interested in how people use and extend Sisu :)

GianMaria.

_______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/sisu-users


Back to the top