[ https://issues.apache.org/jira/browse/FELIX-4598?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14239624#comment-14239624 ]
Tuomas Kiviaho commented on FELIX-4598: --------------------------------------- I noticed that {{ResourceDependencyImpl}} suffers from similar scenario. On top of this both seem not to call {{invokeAdded}} (as {{ServiceDependency}} does) when dependency is required but service has already been instantiated. {code} Index: src/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java =================================================================== --- src/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java (revision 1488970) +++ src/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java (working copy) @@ -35,6 +35,7 @@ import org.apache.felix.dm.ResourceDependency; import org.apache.felix.dm.ResourceHandler; import org.apache.felix.dm.impl.Logger; +import org.apache.felix.dm.impl.SerialExecutor; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.log.LogService; @@ -56,16 +57,16 @@ private URL m_trackedResource; private List m_resources = new ArrayList(); private List m_resourceProperties = new ArrayList(); - private URL m_resourceInstance; - private Dictionary m_resourcePropertiesInstance; private boolean m_propagate; private Object m_propagateCallbackInstance; private String m_propagateCallbackMethod; + private SerialExecutor m_executor; public ResourceDependencyImpl(BundleContext context, Logger logger) { super(logger); m_context = context; m_autoConfig = true; + m_executor = new SerialExecutor(logger); } public ResourceDependencyImpl(ResourceDependencyImpl prototype) { @@ -80,6 +81,7 @@ m_resourceFilter = prototype.m_resourceFilter; m_trackedResource = prototype.m_trackedResource; m_propagate = prototype.m_propagate; + m_executor = prototype.m_executor; } public Dependency createCopy() { @@ -151,6 +153,9 @@ for (int i = 0; i < services.length; i++) { DependencyService ds = (DependencyService) services[i]; if (counter == 1) { + if (ds.isInstantiated() && isInstanceBound() && isRequired()) { + invokeAdded(ds, resource, resourceProperties); + } ds.dependencyAvailable(this); if (!isRequired()) { invokeAdded(ds, resource, resourceProperties); @@ -438,17 +443,44 @@ return URL.class; } - public void invokeAdded(DependencyService service) { - // we remember these for future reference, needed for required callbacks - m_resourceInstance = lookupResource(); - m_resourcePropertiesInstance = lookupResourceProperties(); - invokeAdded(service, m_resourceInstance, m_resourcePropertiesInstance); + public void invokeAdded(final DependencyService service) { + Runnable task = new Runnable() { + + @Override + public void run() { + URL[] resourceInstances; + Dictionary[] resourcePropertiesInstances; + synchronized (this) { + resourceInstances = (URL[]) m_resources.toArray(new URL[m_resources.size()]); + resourcePropertiesInstances = (Dictionary[]) m_resourceProperties.toArray(new Dictionary[m_resourceProperties.size()]); + } + for (int i = 0; i < resourceInstances.length; i++) { + invokeAdded(service, resourceInstances[i], resourcePropertiesInstances[i]); + } + } + + }; + m_executor.execute(task); } - public void invokeRemoved(DependencyService service) { - invokeRemoved(service, m_resourceInstance, m_resourcePropertiesInstance); - m_resourceInstance = null; - m_resourcePropertiesInstance = null; + public void invokeRemoved(final DependencyService service) { + Runnable task = new Runnable() { + + @Override + public void run() { + URL[] resourceInstances; + Dictionary[] resourcePropertiesInstances; + synchronized (this) { + resourceInstances = (URL[]) m_resources.toArray(new URL[m_resources.size()]); + resourcePropertiesInstances = (Dictionary[]) m_resourceProperties.toArray(new Dictionary[m_resourceProperties.size()]); + } + for (int i = 0; i < resourceInstances.length; i++) { + invokeAdded(service, resourceInstances[i], resourcePropertiesInstances[i]); + } + } + + }; + m_executor.execute(task); } public ResourceDependency setPropagate(boolean propagate) { {code} > BundleDependency can effectively track only one bundle > ------------------------------------------------------ > > Key: FELIX-4598 > URL: https://issues.apache.org/jira/browse/FELIX-4598 > Project: Felix > Issue Type: Bug > Components: Dependency Manager > Affects Versions: dependencymanager.runtime-3.2.0 > Reporter: Tuomas Kiviaho > Assignee: Pierre De Rop > Fix For: dependencymanager-4.0.0 > > > Bundles are delivered to callbacks after component is instantiated but prior > to that they can't be. This is the case with ServiceDependencies as well but > unlike them after component instantiation the tracker is not used as source > of bundles but instead lookup method is used. {{ServiceDependencyImpl}} uses > this approach only to gain properties and auto configuration instance. > I suggest that {{BundleDependencyImpl#invokeAdded(DependencyService > service)}} would be implemented in similar manner that > {{ServiceDependencyImpl#invokeAdded(DependencyService service)}} has been > (perhaps also utilizing the serial executor) . -- This message was sent by Atlassian JIRA (v6.3.4#6332)