Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [sisu-users] Sisu in OSGi

On 4 Sep 2013, at 12:48, gian.maria.romanato@xxxxxxxxxxxx wrote:
First of all,

thank you very much for your detailed answers.

> No worries, I'm working on updating the FAQ at the moment so this is
> actually very timely :)


Good to know, I have a few more questions :-)

> The example extender bundle uses Sisu to scan bundles for components
> as they are started:

>
>     https://github.com/eclipse/sisu.inject/blob/master/org.eclipse.
> sisu.inject.
> extender/src/org/eclipse/sisu/launch/internal/SisuActivator.java#L113


I had a look at the source code and made some simple tests with a chain of two bundles, and everything worked like magic :-)
If I understood correctly, the extender instantiates multiple Provider<Injector> objects that will be all registered into the DefaultBeanLocator.

Correct - at the moment it filters on the internal BundleInjector type name when querying the service registry to avoid accidentally picking up unrelated injectors but there's no reason why it couldn't be adapted to pull in injectors registered outside of Sisu. It also casts the resulting service instances to Provider<Injector> rather than the internal BundleInjector type to support refresh of the extender bundle (so you could conceivably update the extender if necessary without disturbing running application bundles). If it attempted to cast them to the current BundleInjector type and the extender bundle had been refreshed then they would not be compatible, but since the Provider and Injector types are imported from outside then they should still be compatible.

The additional registration in the OSGi service using the extended bundle bundlecontext is only used to perform proper removal from the DefaultBeanLocator when the owning bundle goes offline.

Yes - the alternative would be to also handle this using the bundle tracker, but then you'd still need somewhere to keep the reference to the injector and the service registry seems the best place to keep this.

Not related to Sisu, but I noticed that the SisuActivator uses a WeakReference to the DefaultBeanLocator. Is that used for supporting a bundle update/refresh ?

Correct - the idea is that if the extender bundle is refreshed and there is an active locator (ie. at least one previous application bundle is still running) then it will re-use that rather than creating a new locator and potentially splitting the application.

>     *  extend dynamic updates to apply to injected instances, not
> just injected collections (https://bugs.eclipse.org/bugs/show_bug.
> cgi?id=386430)


The above bugzilla entry states that injected lists and maps are already supported. Does it refer to Guice MultiBindings (http://code.google.com/p/google-guice/wiki/Multibindings) or what ?

This is unrelated to multi-bindings - the bean locator returns an iterable sequence of bean entries which can be wrapped into lists, maps, etc. This wrapping is done by the WireModule when it detects that you are injecting a collection. It automatically binds a provider that queries the locator and wraps the result in the appropriate type. The injected collection is backed by the dynamic iterable returned from the locator, meaning that its content will change as injectors are added/removed from the locator. It uses a special ranked sequence under the covers which means we can update the sequence even while you're iterating over it, and also avoid querying potentially expensive sources of bindings (like the Eclipse/OSGi registries) until they are required.


Also, when classes are found via scanning, what happens when multiple implementations of the same interface exist? Does Sisu automatically create a Guice multibinding ?

No, scanned implementations are typically bound using a special wildcard key which means we avoid binding clashes while still allowing the locator to find them when querying on the interfaces. This avoids a combinatorial explosion of bindings and also solves the issue of which interfaces/supertypes to bind against. It also lets the locator query using generic type signatures (even involving bounded type parameters). You can however use the CDI @Typed annotation to force Sisu to bind an implementation to a given list of types.


Does Sisu support Guice's chained linked bindings (http://code.google.com/p/google-guice/wiki/LinkedBindings)?

Sisu is designed to support any kind of binding

I am asking because my application comes with default implementation of certain interfaces and base classes, but we need a simple way of letting developers override them with custom implementations. Ideally such overrides would be implemented in an extra OSGi bundle to be included in the final application distribution. Would a simple Guice module implemented in the extra bundle and declared in META-INF/services/com.google.inject.Module work?

M5 of Sisu will automatically install modules declared in META-INF/services/com.google.inject.Module. Since this is an extra bundle then it is technically a new injector with the overridden bindings (unless you attached it as a fragment to the bundle with the original implementations). To override the original bindings it needs to use a higher ranking (just like a service needs a higher ranking to appear before others) by using the following binding:

bind( RankingFunction.class ).toInstance( new DefaultRankingFunction( myRank ) );

I'm also looking at adding something like a @Rank annotation to let you declare different implementation rankings without having to mess around with the low-level RankingFunction type.

And now my last question, at least for today :-). My application is using the OSGi extender pattern for collecting metadata about classes included in its bundles. If I wanted our extender to create a guice module on-the-fly to bind those classes, I believe I could mimic the behaviour of the BundleInjector class that is included in the Sisu extender. Is that right?

Yes, just use the SpaceModule and WireModule as necessary and register the injector to the locator. Note if you define a binding to the locator instance in your injector then it will be automatically registered by virtue of Guice's automatic instance injection (see the autoPublish method in the locator). Otherwise you'd need to register it manually using the "add(injector, rank)" method.

I would need to refactor the Sisu extender to make some code more reusable, and then have my extender create additional BundleInjectors when appropriate. Would it be an issue for Sisu if more than one BundleInjector exist for the same bundle?

Sisu can handle more than one injector per-bundle if you want. I also agree about making the extender more re-usable. Ideally the useful parts would be moved to the org.eclipse.sisu.inject bundle so others could re-use them in their own extenders/applications, leaving the current extender bundle as a thin Activator. I'm happy to review changes via Gerrit (https://git.eclipse.org/r/), Github (https://github.com/eclipse/sisu.inject) or as patches attached to an issue (https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Sisu&format=guided).

Thanks in advance.
GianMaria Romanato._______________________________________________
sisu-users mailing list
sisu-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/sisu-users


Back to the top