I wrote a test against trunk and don't see this behavior yet. Maybe I didn't
fully understand your scenario. When you say X is removed, does that mean:
ComponentInstance instance = factory.newInstance( props );
X x = instance.getInstance();
instance.dispose();
or are you disabling the component factory, or doing something else?
My test:
public void testFactoryReference() throws Exception
{
String factoryName =
"org.apache.felix.scr.integration.components.factoryreference.FactoryInstance";
final Component component = findComponentByName( factoryName );
TestCase.assertNotNull( component );
TestCase.assertEquals( Component.STATE_FACTORY, component.getState() );
final ServiceReference[] refs = bundleContext.getServiceReferences(
ComponentFactory.class.getName(), "("
+ ComponentConstants.COMPONENT_FACTORY + "=" + "Factory" + ")"
);
TestCase.assertNotNull( refs );
TestCase.assertEquals( 1, refs.length );
final ComponentFactory factory = ( ComponentFactory )
bundleContext.getService( refs[0] );
TestCase.assertNotNull( factory );
Hashtable<String, String> props = new Hashtable<String, String>();
final ComponentInstance instance = factory.newInstance( props );
TestCase.assertNotNull( instance );
TestCase.assertNotNull( instance.getInstance() );
instance.dispose();
TestCase.assertEquals( 0, Service.getDeactivateCount() );
}
configuration:
<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<scr:component
name='org.apache.felix.scr.integration.components.factoryreference.Service'
deactivate='deactivate'>
<service>
<provide
interface='org.apache.felix.scr.integration.components.factoryreference.Service'/>
</service>
<implementation
class='org.apache.felix.scr.integration.components.factoryreference.Service' />
</scr:component>
<scr:component
name='org.apache.felix.scr.integration.components.factoryreference.Component'>
<implementation
class='org.apache.felix.scr.integration.components.factoryreference.Component'
/>
<reference name='service'
interface='org.apache.felix.scr.integration.components.factoryreference.Service'
bind='setService' unbind="unsetService" />
</scr:component>
<scr:component
name='org.apache.felix.scr.integration.components.factoryreference.FactoryInstance'
factory='Factory'>
<implementation
class='org.apache.felix.scr.integration.components.factoryreference.FactoryInstance'
/>
<reference name='service'
interface='org.apache.felix.scr.integration.components.factoryreference.Service'
bind='setService' unbind="unsetService" />
</scr:component>
</components>
If you'd like to see the code I can push it to github.
thanks!
david jencks
On Jan 17, 2013, at 5:00 PM, "Humeniuk, David P"
<[email protected]> wrote:
> I'm using Felix 4.0.2 and SCR 1.6.2 (all components below are DS
> components).
>
>
>
> Actual system is more complicated, but here's basically what I have:
>
>
>
> An immediate component (called MessageServiceImpl) with a service
> reference (call it MessageRouter) and another delayed component (called
> MessageRouterImpl) and it provides MessageRouter. There's another
> component (call it X) that also has a service reference for
> MessageRouter.
>
>
>
> When the delayed component MessgaeRouterImpl is activated, MessageRouter
> is provided and then the immediate component MessageServiceImpl can be
> activated as well as component X (which is a factory component
> instance). Everything works fine until the factory component instance X
> is removed. When component X is removed, the MessageRouterImpl is
> deactivated because the reference count for MessageRouter is 0.
> However, the reference count should be higher, because
> MessageServiceImpl still references it.
>
>
>
> When debugging, I notice that the reference count for MessageRouter is
> decremented twice when the factory component X is disposed. So why does
> this happen? I notice in the stack trace below that
> "AbstractComponentManager$FactoryInstance(AbstractComponentManager$State
> ).doDeactivate" will call deleteComponent at line 1305 that ungets the
> service (and decrements the counter) and deactivateDependencyManagers at
> line 1306 that ungets the service again (and decrements the counter).
>
>
>
> Daemon Thread [Thread-3] (Suspended (breakpoint at line 403 in
> ServiceRegistry))
>
> owns: ServiceRegistry (id=197)
>
> owns: RemoteChannelLookupImpl (id=236)
>
> ServiceRegistry.ungetService(Bundle, ServiceReference)
> line: 403
>
> Felix.ungetService(Bundle, ServiceReference) line: 3432
>
>
> BundleContextImpl.ungetService(ServiceReference) line:
> 486
>
> DependencyManager.ungetService(ServiceReference) line:
> 961
>
> DependencyManager.unbind(Object, ServiceReference[])
> line: 1204
>
> DependencyManager.close(Object) line: 1031
>
>
> ComponentFactoryImpl$ComponentFactoryNewInstance(ImmediateComponentManag
> er).disposeImplementationObject(Object, ComponentContext, int) line: 284
>
>
>
> ComponentFactoryImpl$ComponentFactoryNewInstance(ImmediateComponentManag
> er).deleteComponent(int) line: 152
>
>
> AbstractComponentManager$FactoryInstance(AbstractComponentManager$State)
> .doDeactivate(AbstractComponentManager, int, boolean) line: 1305
>
>
>
> Daemon Thread [Thread-3] (Suspended (breakpoint at line 403 in
> ServiceRegistry))
>
> owns: ServiceRegistry (id=197)
>
> owns: RemoteChannelLookupImpl (id=236)
>
> ServiceRegistry.ungetService(Bundle, ServiceReference)
> line: 403
>
> Felix.ungetService(Bundle, ServiceReference) line: 3432
>
>
> BundleContextImpl.ungetService(ServiceReference) line:
> 486
>
> DependencyManager.ungetService(ServiceReference) line:
> 961
>
> DependencyManager.deactivate() line: 652
>
>
> ComponentFactoryImpl$ComponentFactoryNewInstance(AbstractComponentManage
> r).deactivateDependencyManagers() line: 1065
>
>
> AbstractComponentManager.access$200(AbstractComponentManager) line: 62
>
>
>
> AbstractComponentManager$FactoryInstance(AbstractComponentManager$State)
> .doDeactivate(AbstractComponentManager, int, boolean) line: 1306
>
>
>
> Thanks,
>
> Dave Humeniuk
>
> Software Engineer
>
> Sensor System Division (SSD)
>
> University of Dayton Research Institute
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]