[ 
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)

Reply via email to