Hi,

Am 17.02.2012 um 15:25 schrieb Pierre De Rop:

> Thank you Felix, I tested the fix and it's working fine.

Cool. Thanks for the feedback,

> 
> PS: will you close the issue, or should I ?

I will close it once I cut the release.

Regards
Felix

> 
> regards;
> /Pierre
> 
> On Fri, Feb 17, 2012 at 2:31 PM, Felix Meschberger <fmesc...@adobe.com>wrote:
> 
>> Hi Pierre
>> 
>> I committed a fix, if you like to check. Thanks.
>> 
>> Regards
>> Felix
>> 
>> Am 17.02.2012 um 12:40 schrieb Pierre De Rop:
>> 
>>> Hi Felix,
>>> 
>>> Thanks a lot for reopening this issue.
>>> 
>>> kind regards;
>>> /Pierre
>>> 
>>> On Fri, Feb 17, 2012 at 12:26 PM, Felix Meschberger <fmesc...@adobe.com
>>> wrote:
>>> 
>>>> Hi Pierre,
>>>> 
>>>> Thanks for insisting ...
>>>> 
>>>> I revert my earlier opinion and now think you are right: The
>> satisfaction
>>>> of the ComponentFactory service must include the target properties.
>>>> 
>>>> The newInstance method may be provided with different target property
>>>> values and cause the desired instance to not be satisfiable and thus
>> fail.
>>>> 
>>>> I have reopened the issue and will reconsider your patch.
>>>> 
>>>> Regards
>>>> Felix
>>>> 
>>>> Am 16.02.2012 um 16:10 schrieb Pierre De Rop:
>>>> 
>>>>> Hi everyone,
>>>>> 
>>>>> This post is about a question regarding SCR and especially about SCR
>>>>> Component Factory:
>>>>> 
>>>>> When a component A is defined with a factory attribute, then SCR is
>>>>> intended to register an org.osgi.service.component.ComponentFactory
>>>> inside
>>>>> the registry, in order to allow another component to be injected with
>>>> that
>>>>> ComponentFactory. This way, some other components may programatically
>>>>> instantiate one (or several instances) of the component A.
>>>>> 
>>>>> The question is: should the ComponentFactory be registered only once
>> the
>>>> A
>>>>> component is satisfied
>>>>> (that is: after all A required dependencies are available) ?
>>>>> 
>>>>> I guess yes, because in DS spec, (112.2.4), it is stated the following:
>>>>> 
>>>>> "... SCR must register a Component Factory service on behalf of the
>>>>> component
>>>>> as soon as the component factory is satisfied."
>>>>> 
>>>>> I ask this question because I'm facing the following issue:
>>>>> 
>>>>> I have a component A, which depends on B1(property=b2) like this:
>>>>> 
>>>>> public interface B {
>>>>> }
>>>>> 
>>>>> @Component(factory = "A")
>>>>> public class A /* implements something which required B2 */ {
>>>>>  @Reference(target = "(property=b2)")
>>>>>  void bind(B b, Map<?, ?> properties) {
>>>>>      System.out.println("A.bind(b=" + b + ", properties=" + properties
>>>> +
>>>>> ")");
>>>>>  }
>>>>> 
>>>>>  @Activate
>>>>>  void start() {
>>>>>      System.out.println("A.start");
>>>>>  }
>>>>> }
>>>>> 
>>>>> And here is the component which is in charge of instantiating A:
>>>>> 
>>>>> @Component
>>>>> public class AFactory {
>>>>>  @Reference(target = "(component.factory=A)")
>>>>>  void bind(ComponentFactory aFactory) {
>>>>>      System.out.println("AFactory: bound aFactory=" + aFactory);
>>>>>      try {
>>>>>          ComponentInstance ci = aFactory.newInstance(null);
>>>>>          A a = (A) ci.getInstance();
>>>>>          System.out.println("AFactory: created instance of a: " + a);
>>>>>      }
>>>>>      catch (Throwable t) {
>>>>>          t.printStackTrace();
>>>>>      }
>>>>>  }
>>>>> }
>>>>> 
>>>>> Now, I have B1, defined like this:
>>>>> 
>>>>> @Component(properties = { "property=b1" })
>>>>> public class B1 implements B {
>>>>> }
>>>>> 
>>>>> and I then have B2 (which is the one required by A):
>>>>> 
>>>>> @Component(enabled=false, properties = { "property=b2" })
>>>>> public class B2 implements B {
>>>>> }
>>>>> 
>>>>> Here, B2 is declared with "enabled=false", meaning that the component
>> B2
>>>> is
>>>>> not activated by default, at startup time.
>>>>> So, B2 is meant to be manually enabled from web console.
>>>>> 
>>>>> So, what I expect is the following:
>>>>> 
>>>>> 1) When B2 is enabled from web console (using the "Component" menu),
>> then
>>>>> B2 is registered in the registry.
>>>>> 2) At this point, I expect A to become satisfied, because A is
>> depending
>>>> of
>>>>> service B2 (with property=b2).
>>>>> 3) Then I expect the ComponentFactory of A to be registered in the OSGi
>>>>> registry.
>>>>> 4) Finally, AFactory is activated, and then instantiates A (using the
>>>>> injected A ComponentFactory).
>>>>> 
>>>>> The problem is that when I start the framework, it seems that the
>>>> AFactory
>>>>> component is immediately registered
>>>>> with the ComponentFactory of A, while at this point A is not yet
>>>> satisfied
>>>>> (because at startup, only B1 is available, and
>>>>> B2 is not yet available). So when AFactory instantiates A (using
>>>>> ComponentFactory.newInstance), I then get the exception:
>>>>> 
>>>>> g! AFactory: bound aFactory=Component: test.scr.factory.A (1)
>>>>> org.osgi.service.component.ComponentException: Failed activating
>>>> component
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.ComponentFactoryImpl.newInstance(ComponentFactoryImpl.java:120)
>>>>>      at test.scr.factory.AFactory.bind(AFactory.java:15)
>>>>>      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>>      at
>>>>> 
>>>> 
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>>>      at
>>>>> 
>>>> 
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>>>      at java.lang.reflect.Method.invoke(Method.java:597)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.helper.BaseMethod.invokeMethod(BaseMethod.java:227)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.helper.BaseMethod.access$500(BaseMethod.java:38)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.helper.BaseMethod$Resolved.invoke(BaseMethod.java:595)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.helper.BaseMethod$NotResolved.invoke(BaseMethod.java:552)
>>>>>      at
>>>>> org.apache.felix.scr.impl.helper.BaseMethod.invoke(BaseMethod.java:476)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.DependencyManager.invokeBindMethod(DependencyManager.java:1028)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.DependencyManager.bind(DependencyManager.java:944)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.DependencyManager.open(DependencyManager.java:868)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.ImmediateComponentManager.createImplementationObject(ImmediateComponentManager.java:200)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.ImmediateComponentManager.createComponent(ImmediateComponentManager.java:118)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager$Unsatisfied.activate(AbstractComponentManager.java:1140)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:334)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.DependencyManager.serviceAdded(DependencyManager.java:283)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.DependencyManager.serviceChanged(DependencyManager.java:170)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:932)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:793)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:543)
>>>>>      at
>>>>> org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4260)
>>>>>      at
>>>> org.apache.felix.framework.Felix.registerService(Felix.java:3275)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:346)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.ComponentFactoryImpl.registerService(ComponentFactoryImpl.java:173)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager.registerComponentService(AbstractComponentManager.java:508)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager$Unsatisfied.activate(AbstractComponentManager.java:1157)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:334)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.DependencyManager.serviceAdded(DependencyManager.java:283)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.DependencyManager.serviceChanged(DependencyManager.java:170)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:932)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:793)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:543)
>>>>>      at
>>>>> org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4260)
>>>>>      at
>>>> org.apache.felix.framework.Felix.registerService(Felix.java:3275)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:346)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:456)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager.registerComponentService(AbstractComponentManager.java:508)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager$Unsatisfied.activate(AbstractComponentManager.java:1157)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:334)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:158)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.config.ImmediateComponentHolder.enableComponents(ImmediateComponentHolder.java:313)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.BundleComponentActivator.loadDescriptor(BundleComponentActivator.java:241)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.BundleComponentActivator.initialize(BundleComponentActivator.java:147)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.scr.impl.BundleComponentActivator.<init>(BundleComponentActivator.java:111)
>>>>>      at
>>>>> org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:274)
>>>>>      at
>>>>> org.apache.felix.scr.impl.Activator.bundleChanged(Activator.java:192)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:868)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:789)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:514)
>>>>>      at
>>>> org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4244)
>>>>>      at org.apache.felix.framework.Felix.startBundle(Felix.java:1923)
>>>>>      at
>>>>> org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191)
>>>>>      at
>>>>> 
>>>> 
>> org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295)
>>>>>      at java.lang.Thread.run(Thread.java:662)
>>>>> 
>>>>> And after I enable B2 from webconsole, then nothing happens, and
>> AFactory
>>>>> is not injected with the A Component Factory anymore.
>>>>> 
>>>>> Am I making sense with all this ? Is there really an issue in SCR to be
>>>>> reported in jira ?
>>>>> (I reported this in an old issue FELIX-3090 which is currently closed,
>>>> but
>>>>> I still feel there is something to it).
>>>>> 
>>>>> thanks for your help;
>>>>> 
>>>>> /pierre
>>>> 
>>>> 
>> 
>> 

Reply via email to