Bugfixes for several issues with required service dependencies with callbacks in scenarios where multiple dependencies are available.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1039035 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/pom.xml b/dependencymanager/core/pom.xml
index becf540..e6bae60 100644
--- a/dependencymanager/core/pom.xml
+++ b/dependencymanager/core/pom.xml
@@ -55,7 +55,7 @@
<Private-Package>org.apache.felix.dm.impl,org.apache.felix.dm.impl.dependencies,org.apache.felix.dm.impl.tracker,org.apache.felix.dm.impl.metatype</Private-Package>
<!-- Uncomment this line to include source code in the bundle.
<Include-Resource>src/main/java</Include-Resource>
- -->
+ -->
</instructions>
</configuration>
</plugin>
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
index c9ee905..618a211 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
@@ -25,10 +25,10 @@
import java.util.List;
import java.util.Map;
-import org.apache.felix.dm.Dependency;
-import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@@ -184,8 +184,7 @@
public void removed(URL resource) {
Component newService = (Component) m_services.remove(resource);
if (newService == null) {
- System.out.println("Service should not be null here, dumping stack.");
- Thread.dumpStack();
+ throw new IllegalStateException("Service should not be null here.");
}
else {
m_manager.remove(newService);
@@ -202,8 +201,7 @@
public void removed(ServiceReference ref, Object service) {
Component newService = (Component) m_services.remove(ref);
if (newService == null) {
- System.out.println("Service should not be null here, dumping stack.");
- Thread.dumpStack();
+ throw new IllegalStateException("Service should not be null here.");
}
else {
m_manager.remove(newService);
@@ -220,8 +218,7 @@
public void removed(Bundle bundle) {
Component newService = (Component) m_services.remove(bundle);
if (newService == null) {
- System.out.println("Service should not be null here, dumping stack.");
- Thread.dumpStack();
+ throw new IllegalStateException("Service should not be null here.");
}
else {
m_manager.remove(newService);
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ComponentImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ComponentImpl.java
index b1bb057..fc9c0d8 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ComponentImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ComponentImpl.java
@@ -1008,21 +1008,12 @@
}
private void unconfigureServices(State state) {
- System.err.println("unconfigureServices " + state);
Iterator i = state.getDependencies().iterator();
while (i.hasNext()) {
Dependency dependency = (Dependency) i.next();
if (dependency.isRequired()) {
- System.err.println("unconfigureServices invokeremoved " + dependency);
dependency.invokeRemoved(this);
}
-// if (dependency instanceof ServiceDependencyImpl) {
-// ServiceDependencyImpl sd = (ServiceDependencyImpl) dependency;
-// // for required dependencies, we invoke any callbacks here
-// if (sd.isRequired()) {
-// sd.invokeRemoved(this, sd.lookupServiceReference(), sd.lookupService());
-// }
-// }
}
}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
index e1e471b..7d37db5 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
@@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.Dictionary;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -37,7 +38,6 @@
import org.apache.felix.dm.DependencyService;
import org.apache.felix.dm.InvocationUtil;
import org.apache.felix.dm.ServiceDependency;
-import org.apache.felix.dm.ServiceUtil;
import org.apache.felix.dm.impl.DefaultNullObject;
import org.apache.felix.dm.impl.Logger;
import org.apache.felix.dm.tracker.ServiceTracker;
@@ -75,10 +75,10 @@
private Object m_defaultImplementation;
private Object m_defaultImplementationInstance;
private boolean m_isAvailable;
- private ServiceReference[] m_references;
private boolean m_propagate;
private Object m_propagateCallbackInstance;
private String m_propagateCallbackMethod;
+ private Map m_sr = new HashMap(); /* <DependencyService, Set<ServiceReference>> */
private static final Comparator COMPARATOR = new Comparator() {
public int getRank(ServiceReference ref) {
@@ -443,7 +443,11 @@
// because if not, then our dependency would not be active); or the dependency is required,
// meaning that either the service is not yet started, or already started.
// In all cases, we have to inject the required dependency.
- invokeAdded(ds, ref, service);
+
+ // we only try to invoke the method here if we are really already instantiated
+ if (ds.isInstantiated() && ds.getCompositionInstances().length > 0) {
+ invokeAdded(ds, ref, service);
+ }
}
}
}
@@ -465,8 +469,6 @@
public void removedService(ServiceReference ref, Object service) {
boolean makeUnavailable = makeUnavailable();
- System.out.println("removedService: " + makeUnavailable + " for " + ServiceUtil.toString(ref));
-
Object[] services;
synchronized (this) {
services = m_services.toArray();
@@ -490,10 +492,16 @@
}
+
public void invokeAdded(DependencyService dependencyService, ServiceReference reference, Object service) {
- invoke(dependencyService, reference, service, m_callbackAdded);
- //marrs
- m_refs.add(reference);
+ Set set = (Set) m_sr.get(dependencyService);
+ if (set == null) {
+ set = new HashSet();
+ m_sr.put(dependencyService, set);
+ }
+ if (set.add(reference)) {
+ invoke(dependencyService, reference, service, m_callbackAdded);
+ }
}
public void invokeChanged(DependencyService dependencyService, ServiceReference reference, Object service) {
@@ -501,9 +509,10 @@
}
public void invokeRemoved(DependencyService dependencyService, ServiceReference reference, Object service) {
- invoke(dependencyService, reference, service, m_callbackRemoved);
- //marrs
- m_refs.remove(reference);
+ Set set = (Set) m_sr.get(dependencyService);
+ if (set != null && set.remove(reference)) {
+ invoke(dependencyService, reference, service, m_callbackRemoved);
+ }
}
public void invoke(DependencyService dependencyService, ServiceReference reference, Object service, String name) {
@@ -809,48 +818,29 @@
return "service";
}
- private List m_refs = new ArrayList();
-
public void invokeAdded(DependencyService service) {
ServiceReference[] refs = m_tracker.getServiceReferences();
if (refs != null) {
for (int i = 0; i < refs.length; i++) {
ServiceReference sr = refs[i];
Object svc = m_context.getService(sr);
- System.out.println("invokeAdded " + i + " " + ServiceUtil.toString(sr));
invokeAdded(service, sr, svc);
-
- //marrs
- m_refs.add(sr);
}
}
- m_references = refs;
-
}
public void invokeRemoved(DependencyService service) {
- ServiceReference[] refs = m_references;
-
-
- if (refs != null) {
- //marrs
- refs = (ServiceReference[]) m_refs.toArray(refs);
-
- for (int i = 0; i < refs.length; i++) {
- ServiceReference sr = refs[i];
- Object svc = m_context.getService(sr);
- System.out.println("invokeRemoved " + i + " " + ServiceUtil.toString(sr));
- if (sr.getBundle() == null) {
- System.out.println("invokeRemoved OLD SHIT .. SKIPPING .. not");
-// break;
- }
- invokeRemoved(service, sr, svc);
- }
+ Set references = (Set) m_sr.get(service);
+ ServiceReference[] refs = (ServiceReference[]) (references != null ? references.toArray(new ServiceReference[references.size()]) : new ServiceReference[0]);
+
+ for (int i = 0; i < refs.length; i++) {
+ ServiceReference sr = refs[i];
+ Object svc = m_context.getService(sr);
+ invokeRemoved(service, sr, svc);
}
- m_references = null;
-
- //marrs
- m_refs.clear();
+ if (references != null) {
+ references.clear();
+ }
}
public Dictionary getProperties() {