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