[
https://issues.apache.org/jira/browse/FELIX-4050?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13656128#comment-13656128
]
Pierre De Rop commented on FELIX-4050:
--------------------------------------
I'm not sure I fully understand the described issue.
May be you could attach a sample code reproducing the exact problem you are
describing ?
In the mean time, here is more information about the @Init annotation, and also
about the @ServiceDependency used with a "name" attribute:
1- @Init annotation:
==============
>From the method annotated with @Init, you are allowed to dynamically add
>dependencies using the API.
For instance, assuming that S depends on S1/S2/S3, you can then declare "S" as
in the following example:
@Component
public class S {
// required dependency on service "S1"
@ServiceDependency
S1 _s1;
// S2, which dependency is dynamically added in init() method
S2 _s2;
// S3, which dependency is dynamically added in init() mehtod
S3 _s3;
// Inject the API, used by our init() method
@Inject
org.apache.felix.dm.Component _c;
// Atomically adds dependencies on S2/S3
@Init
void init() {
List l = new ArrayList();
l.add(_c.getDependencyManager().createServiceDependency()
.setService(S2.class)
.setRequired(true)
.setAutoConfig("_s2")
.setInstanceBound(true));
l.add(_c.getDependencyManager().createServiceDependency()
.setService(S3.class, "(foo=bar)")
.setRequired(true)
.setAutoConfig("_s3")
.setInstanceBound(true));
_c.add(l);
}
@Start
void start() {
System.out.println("started: s2=" + _s2 + ", s3=" + _s3);
}
}
In the init() method, notice the following important points:
- S2/S3 dependencies are added atomically, using Component.add(List) method.
When more than one dependency is added from the init() method, it is better to
add them using a List, because List of Dependencies are
added atomically: doing so prevent the @Start method to be called if the first
dependency (S2) is available before we add the last dependency S3.
Here, the @Start method will be called only after S2 and S3 dependencies have
been added and are available.
- the S2/S3 extra dependencies are "instance bound": it means that even if S2
and/or S3 are not available, then "S" component won't be
destroyed immediately.
You can refer to the following post, where Marcel explains "instance bound"
dependencies:
http://www.mail-archive.com/[email protected]/msg09314.html
2- Named @ServiceDependencies
=========================
Now, let's describe when to declare a @ServiceDependency with a "name"
attribute:
"named" dependencies are only available using the annotations, not using the
API.
When you declare a @ServiceDependency with a "name" attribute, you can
configure its 'required' flag and its filter by returning a Map from the @Init
method.
For instance, assuming that you want to configure the S2 'required' flag and
also its filter from ConfigAdmin, then you can do it like this:
@Component
public class S {
// Config Admin properties, where the S2 'required' flag and filter is
configured
private Dictionary config;
// Inject our configuration
@ConfigurationDependency(pid="MyPid")
void configure(Dictionary config) {
this.config = config;
}
// S2 dependency, whose 'required' flag and filter is dynamically
configured from init() method.
@ServiceDependency(name="S2")
S2 s2;
/**
* Configure our "S2" dependency, using the already injected configuration.
* The returned Map will be used to configure our "S2" Dependency (see
above).
* The convention is: each Map keys must be prefixed with a dependency
name, and must then
* be suffixed with either "filter" (for the dependency filter) or
"required" (for the dependency 'required' flag).
*/
@Init
Map init() {
return new HashMap() {{
put("S2.filter", m_config.get("filter"));
put("S2.required", m_config.get("required"));
}};
}
@Start
void start() {
System.out.println("started: s2=" + _s2 + ", s3=" + _s3);
}
}
You can refer to the following documentation for more information about named
dependencies:
http://felix.apache.org/site/apache-felix-dependency-manager-using-annotations-lifecycle.html
Please, check "Dynamic Dependency Configuration" section.
by the way, I just saw that dependencymanager documentation is somewhat broken
from URL:
http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/apache-felix-dependency-manager-using-annotations.html
Please refer to the old site for dm annotation documentation:
http://felix.apache.org/site/apache-felix-dependency-manager-using-annotations.html
(I will fix the doc from http://felix.apache.org/documentation asap).
> Named dependencies are not injected if new dependencies are added at init
> phase.
> --------------------------------------------------------------------------------
>
> Key: FELIX-4050
> URL: https://issues.apache.org/jira/browse/FELIX-4050
> Project: Felix
> Issue Type: Bug
> Components: Dependency Manager
> Affects Versions: dependencymanager-3.1.0
> Reporter: Tuomas Kiviaho
>
> Spec says that "In the Init method, you are yet allowed to add some
> additional dependencies (but using the API)."
> I guess this means that I am allowed to call Component.add(). This leads to
> state transition for instance when new service dependency is added since it's
> started right away because component is already instantiated at this point.
> Component.dependencyAvailable() is called if service tracker finds a match
> right away and this in turn starts the state change calculation.
> Problem is that State uses components current instantiated status to
> determinate whether it is bound or not and not the status what the component
> was given to the activateService() method. State change calculation
> transitions to bound state prematurely because component is now instantiated.
> All required dependencies are available, because component is still unaware
> of forthcoming named dependencies at this point.
> I suggest that some sort of placeholder dependencies are used which the named
> dependencies will replace when they are created/configured. This also
> approach also preserves the order in which dependencies were actually added
> to the component. In the future there could be a new is/SetActive property to
> DependencyActivation which could be used to turn on/off an already added
> dependencies. Then named dependencies could be used as such instead of
> placeholders and user could even configure them directly.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira