[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[sisu-dev] Problem sharing method interceptors
|
Hello,
I am using Sisu 0.2.0 in an OSGi container
and I am trying to share the definition of an AOP method interceptor across
multiple bundles.
According to https://bugs.eclipse.org/bugs/show_bug.cgi?id=403108
this should be done by listing the module that binds the method interceptor
in the META-INF/sisu/com.google.inject.Module file of each bundle who wants
to use the same interceptor.
Since I did not like the idea to declare
the same module multiple times, following a suggestion by Stuart I customised
the default extender and changed SisuTracker and SisuBundlePlan so that
the extender creates a new instance of the shared module each time it creates
a Guice Injector for a bundle. This was achieved by letting the shared
module implement a custom marker interface (Shared), by making it bind
itself under that marker interface in the configure() method, and
by using the bean locator to locate all shared modules so that they could
be instantiated and passed to the bundle injector to be created. In other
words, once the shared module is created by SisuExtensions, it is known
to the bean locator and can be found and instantiated by the extender to
extend bundles that are started later.
In practice, I overrode method compose()
of SisuBundlePlan.
@Override
protected
Module compose(Bundle bundle) {
Key<Shared>
key = Key.get(Shared.class);
Iterable<?
extends
BeanEntry<Annotation, Shared>> result = locator.locate(key);
List<Module>
extraModules = new
ArrayList<Module>(builtInModules);
for
(BeanEntry<Annotation, Shared> entry : result) {
Shared value = entry.getValue();
extraModules.add(value);
}
return
new
CustomModule(bundle, locator,
extraModules);
}
builtInModules is a class field holding
list of modules that are passed to each BundleModule by my custom extender.
It includes the LifeCycleModule and another module of mine, let's call
it ModuleA. A new instance is created for every extended bundle.
Finally, CustomModule is an extension
of BundleModule to change the way the BeanScanning strategy is selected
and to override modules() method as follows:
@Override
protected
List<Module> modules() {
ArrayList<Module>
all = new
ArrayList<Module>();
all.addAll(super.modules());
all.addAll(builtInModules);
return
all;
}
I created a singleton DefaultBeanLocator
instance in my custom extender and use it at a later time to perform instantiation
and injection in this way:
Key<T>
key = Key.get(type);
Iterator<?
extends
Entry<?, T>> i = beanLocator.locate(key).iterator();
if
(i.hasNext()) {
return
i.next().getValue();
}
Now, the problem is that when I request
instantiation of a class that should be subject to the method interceptor,
I am returned an instance of the plain class instead of the class enhanced
by Guice to support the interceptor.
But, another method interceptor defined
by my ModuleA works as expected.
Finally, I made the following test. I
used the bean locator to locate all the Guice Injectors it knows, and tried
instantiating my annotated class with any of those. Looks like more than
one of them are capable of instantiating my annotated class, and only one
of them is correctly returning the class enhanced by Guice, the one created
for the bundle that declares the annotated class, while the other
Injector that shows up earlier in the list do not know the interceptor
but still returns a not-enhanced instance of my annotated class:
Bundle1
Bundle2
- depends on Bundle1
- defines the shared module declaring the
AOP interceptor
- defines the annotated class that should
be subject to AOP
When I ask the singleton bean locator
to instantiate the annotated class, the class is found by the Injector
created for Bundle1! and it is returned not enhanced.
If I iterate over all injectors known
to the bean locator, I see that the injector for Bundle2 correctly returns
the enhanced class.
So far I cound not figure out what the
source of the problem could be, and why the injector for Bundle1 returns
the instance of a class that is defined in another bundle that is started
later. I thought I could have messed up with the BundleClassSpace in my
extender, but that does not seem to be the case, as the BundleClassSpace
is created using the right bundlecontext.
Any hint about a possible source of the
problem?
Thanks in advance.
GianMaria.