You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Dependency Handler

The dependency handler manage dependency elements. Each dependency element represent a service dependency.

Dependency

A dependency represents a required service. Therefore, it manages the service lookup and the service invocation. The dependency affects directly the component state, and must manage correctly the dynamics of OSGi to allow a complete unloading when a service goes away.

Metadata

Dependency Metadata

FIGURE Dependency Metadata

The previous image shows you the dependency UML class. Some of these attributes are optional (0...1). Indeed, either the component code contains the information; either iPOJO uses a default behaviour.
The interface attribute describes the required service. This element is optional because the component implementation contains the same information (the type of the field). If the interface attribute has a value, the consistency of the information is checked.
The filter attribute contains the LDAP request on the service. As default, iPOJO use no filter, but you can specify a filter. For further information, see the OSGi specification.
The optional attribute describes if the dependency is optional or not. An optional dependency is always valid, and does not interact with the component state. On the other hand, when a mandatory is no more valid the component state becomes INVALID.
The field attribute is mandatory. The field attribute contains the name of the field of the component attached with this dependency.
Remark that the multiple information on a dependency is not described in the metadata. Indeed, a dependency is set to multiple when the code contains an array. So the HelloService[] m_hello field describe a multiple dependency, but HelloService m_hello describe a simple dependency.

Metadata Examples

XML Metadata

Example 1: <Dependency optional="false" field="m_hello"/> => Mandatory dependency attached to the m_hello field.
Example 2: <Dependency optional="true" field="m_log"/> => Optional Dependency attached to the m_log field
Example 3: <Dependency interface="org.osgi.log.LogService" optional="true" field="m_log"/> => Optional dependency attached to the m_log field, the interface of the service is org.osgi.log.LogService
Example 4: <Dependency filter="(language=fr)" optional="true" field="m_dictionnay"/> => Optional dependency attached to the m_dictionnary field. The language of the needed service need be "fr".

Manifest Metadata

Example 1: Dependency { $optional="true" $field="m_hello"}
Example 2: Dependency { $optional=false $field="m_log"}
Example 3: Dependency { $interface="org.osgi.log.LogService" $optional="true" $field="m_log"}
Example 4: Dependency { $filter="(language=fr)" $optional="true" $\ield="m_dictionnay"}

Technical details on service discovery and service invocation

In fact, the container of the component contains a "Dependencies Manager" managing all the service dependency of the component. To do this, it registers an OSGi service event listener and listens for interesting events. When an interesting service arrives, it stores the service reference. When the service is used, it obtains the service object and returns the object to the component. If it is a multiple dependencies, it returns an array of service object. When a service goes away, the dependencies manager removes the reference from its list: the manager does not keep any reference on the old service. This allows a complete unloading of the service.

Note about simple optional dependency

The component implementation can use an optional dependency without any checking. Indeed, when a component declares an optional dependency, iPOJO create on the fly a Nullable class implementing the service specification but doing nothing. Therefore, iPOJO cannot return a service to the component, for an optional dependency, it returns a nullable object.

A nullable object returns:

  • Null when the method returns an object
  • 0 when the method returns an int, log, byte, short, float or a double
  • False when the method return a Boolean

You can check if the returned object is a nullable object with the test: m_myservice instanceof Nullable

H3. Note about synchronization
When you want to be sure to have always the same service objects, you can use a synchronized block. It is useful for multiple dependencies. Indeed when you want to be sure that a service does not go away during the iteration on your array, you can put your loop inside a synchronized block. Your mutex object should be "this".

Limitations

By hiding all the aspect about service discovery and service invocation, we lost some important features:

  • You cannot have the service properties if there is not method to call it in the service interface.
  • You cannot change dynamically the filter on a service request.
  • Two calls to a service can use two different service implementations if the used implementation has gone. iPOJO tries to return always the same service object, since the service goes away.
  • Many works about the synchronization need to be done.
  • No labels