121 Blueprint Container Specification

121.1 Introduction

One of the great promises of object oriented languages was the greater reuse it should enable. However, over time it turned out that reuse was still hard. One of the key reasons was coupling. Trying to reuse a few classes usually ended up in dragging in many more classes, that in their turn dragged in even more classes, ad nauseum.

One of the key innovations in the Java language to address this coupling issue were interfaces. Interfaces significantly could minimize coupling because they were void of any implementation details. Any class can use an interface, where that interface can be implemented by any other class. However, coupling was still necessary because objects need to be created, and for creating an object its concrete class is necessary.

One of the most successful insights in the software industry of late has been inversion of control, or more specific dependency injection. With dependency injection, an object is given the collaborators that it needs to work with. By not creating these dependencies itself, the object is not coupled to the concrete type of these implementations and their transitive implementation dependencies. However, these objects are not useful on their own, they can only function when an external party provides these objects with their collaborating objects.

An injection framework creates these objects, and also their concrete dependencies, and wires them together. Injection frameworks can significantly increase reuse and provide increased flexibility. For example, during testing it is possible to inject mocked up objects instead of the actual objects.

There exists a number of these injection frameworks in the market, for example [1] Spring Framework, [3] Guice, and [4] Picocontainer. These containers are configured with XML, Java annotations, or provide automatic configuration based on types.

Decoupling is one of the primary drivers for the OSGi specifications. The module layer provides many mechanisms to hide implementation details and explicitly defines any dependencies. The service layer provides a mechanism to collaborate with other bundles without caring about who that other bundle is. However, using the OSGi APIs to construct an application out of services and objects also implies coupling to these OSGi APIs.

This specification therefore defines a dependency injection framework, specifically for OSGi bundles, that understands the unique dynamic nature of services. It provides an OSGi bundle programming model with minimal implementation dependencies and virtually no accidental complexity in the Java code. Bundles in this programming model contain a number of XML definition resources which are used by the Blueprint Container to wire the application together and start it when the bundle is active.

This Blueprint Container specification is derived from the [2] Spring Dynamic Modules project.

121.1.1 Essentials

  • Dependency Injection Framework - Provide an advanced dependency injection framework for bundles that can create and wire objects and services together into an application.

  • Inversion of Control - (IOC) A pattern in which a framework/library provides the control over the component instances instead of the other way around. Dependency injection is a form of IOC.

  • Extender Model - Enable the configuration of components inside a bundle based on configuration data provided by the bundle developer. The life cycle of these components is controlled by the extender based on the extended bundle's state.

  • Unencumbered - Do not require any special bundle activator or other code to be written inside the bundle in order to have components instantiated and configured.

  • Services - Enable the usage of OSGi services as injected dependencies.

  • Dependencies - Allow components to depend on other components like services and beans as well as register as services, with the full breadth of the OSGi capabilities.

  • Dynamicity - Minimize the complexity of using the dynamicity of services

  • Business Logic - A focus on writing business logic in regular Java classes that are not required to implement certain framework APIs or contracts in order to integrate with a container.

  • Declarative - This facilitates independent testing of components and reduces environment dependencies.

  • Familiarity - Familiar to enterprise Java developers.

121.1.2 Entities

  • Blueprint Extender - The bundle that creates and injects component instances for a Blueprint bundle as configured in that Blueprint bundle's XML definition resources.

  • Blueprint Container - Represents the activities of the Blueprint Extender for a specific Blueprint Bundle.

  • Blueprint Bundle - A bundle that is being constructed by the Blueprint Container because it has a Bundle-Blueprint header or it contains XML resources in the OSGI-INF/blueprint directory.

  • Manager - A manager is responsible for the life cycle of all component instances for one component definition. There are the following types of managers. A manager is a bean manager, a service reference manager, or a service manager. A manager can have explicit and implicit dependencies on other manager. During instantiation and runtime, a manager can provide a component instance to be injected or used in other ways.

  • Component - A loosely defined term for the application building blocks and their infrastructure. Components are instantiated into component instances by a manager that is configured with a Component Metadata subclass that is derived from a Component Definition.

  • Component Instance - An object that is part of the application. Component Instances are created and managed by their component manager.

  • Component Definition - Configuration data used by a manager to construct and manage component instances. This configuration data is represented in Metadata, an interface hierarchy starting with the Metadata interface.

  • Bean Manager - A manager that has metadata for creating Java objects and injecting them with objects and component instances that come from other managers it implicitly depends on.

  • Service Manager - A manager that handles the registration of a service object that is provided by a component instance.

  • Service Reference Manager - The general name for the reference and reference-list managers.

  • Reference Manager - A manager that handles the dependency on a single OSGi service.

  • Reference-list Manager - A manager that handles the dependency on a list of OSGi services.

  • Environment Manager - A manager that can provide information from the Bundle's environment. For example, the BlueprintContainer object is made available through an environment manager.

  • Target - A manager type useful in a callback context. These are the ref (which is an indirection to), a reference, and a bean manager.

  • Property - A conceptual instance variable of a component instance provided by a bean manager that is set on the component instance with a corresponding set<Name> method.

  • Argument - Metadata for an argument in a constructor or method.

  • Type Converter - A component instance defined, or referenced, in the type-converters section implementing the Converter interface.

Figure 121.1 Blueprint Class and Service Overview

Blueprint Class and Service Overview

121.1.3 Synopsis

The Blueprint Extender bundle waits for Blueprint bundles. These are bundles that contain Blueprint XML resources called the definitions. These XML resources can be found in a fixed location or pointed to from a manifest header. When a Blueprint extender bundle detects that a Blueprint bundle is ready, it creates a Blueprint Container to manage that Blueprint bundle.

The Blueprint Container then parses the definitions into metadata objects. All top-level elements in the definitions are ComponentMetadata objects and are registered in the Blueprint Container by their id.

For each of the ComponentMetadata objects, the Blueprint Container has a corresponding component manager. For example, a BeanMetadata object relates to a Bean Manager instance. There are the following types of managers:

  • Bean Managers - Can provide general objects that are properly constructed and configured

  • Service Managers - Can register services

  • Service Reference Managers - Provide proxies to one or more services. There are two sub-types: reference-list and reference.

  • Environment Managers - Holding environment values like the Blueprint Bundle object

After creation, all managers are not yet activated. A manager is activated on demand when it has to provide a component instance for the first time.

All service reference managers track services in the service registry in order to determine if they are satisfied or not. If not, the Blueprint Container can optionally start a grace period. During the grace period, the Blueprint Container waits for all mandatory service reference managers to become satisfied. If this does not happen during the grace period, the Blueprint Container must abort the initialization.

From now on, the Blueprint Container is ready to provide component instances. Whenever a manager is asked to provide a component instance for the first time, the manager is activated. This activation will first request all its dependencies to provide a component instance, activating these managers if not already activated, recursively.

However, the activation needs a trigger to start. There are two triggers.

  • Service Request - All service managers must have a Service Factory registered with the OSGi service registry whenever that service manager is enabled, see Enabled.

  • Eager Managers - To kick start the application in the bundle, the Blueprint Container must ask all eager managers to provide a component instance, thereby activating these managers, see Eager Instantiation.

Service references must actuate their reference listeners when they are activated.

Bean managers have a scope. This scope can be singleton, where the manager always provides the same object, or prototype, where the manager creates a new object for each request.

Service reference managers provide proxies to the actual service objects and fetch the service object lazily. They provide a constant reference that dampen the dynamics of the underlying service objects.

If the Blueprint Container has successfully activated the eager managers, it will register a Blueprint Container service.

When the Blueprint Container must be destroyed because: the Blueprint bundle has stopped, there is a failure, or the Blueprint extender is stopped, then the Blueprint Container service is unregistered and all managers are deactivated. This will unregister any services and disable listeners, which release the component instances. Then all component instances are destroyed in reverse dependency order. That is, a component instance is destroyed when no other component instances depend on it.

121.2 Managers

The key feature of the Blueprint Container specification is to let the application in the bundle be constructed in the proper order from objects that are not required to be aware of Blueprint, OSGi, or even each other. These objects are called component instances. The active entity that orchestrates the life cycle of the bundle application is the Blueprint Container. It is configured by XML resources in the Blueprint bundle. The Blueprint Container is responsible for construction and configuration of the component instances as well as the interaction with the service registry.

Inside the Blueprint Container, component instances are managed by a manager. A manager is configured with one Component Definition, for example a bean definition, and can then provide one or more component instances. Such a configured manager instance is also loosely called a component.

A manager can have additional behavior associated with it. This behavior is controlled by the manager's type. This specification defines a number of manager types: bean, service, environment, reference, and reference-list. These types are further defined in the next section.

These managers are conceptual, they are not visible in the API of this specification. That is, an implementation is free to implement the specification without these objects as long as the externally observable behavior is the same.

As an example, a trivial echo service:

<blueprint>
   <service id="echoService" 
            interface="com.acme.Echo" ref="echo"/>
   <bean id="echo" class="com.acme.EchoImpl">
     <property name="message" value="Echo: "/>
   </bean>
</blueprint>

public interface Echo {
  public String echo(String m);
}
public class EchoImpl implements Echo {
  String message;
  public void setMessage(String m) {
    this.message= m;
  }
  public void echo(String s) { return message + s; }
}  

The example defines two top-level managers: echoService and echo. The echoService manager is of type service, and the echo manager is of type bean. The service manager is responsible for registering an OSGi service, where the service object will be the component instance provided by the echo manager. The echo component instance gets a message injected.

As seen from the example, managers can use component instances from other managers to construct their component instances. The use of other managers creates an implicit dependency. Managers can also declare explicit dependencies. Dependencies are transitive, see Manager Dependencies for more information. In the previous example, the echoService service manager depends on the echo manager, this is an implicit dependency.

Managers have their own life cycle. They are conceptually created after the Blueprint Container has decided to run the application, see Blueprint Life-Cycle. However, the intention of this specification is to allow the bundle application to lazily activate. That is, no application code is used until there is a trigger like a service request or a service manager has an explicit dependency. A manager must always be atomically activated before it provides its first component instance. During activation, listeners are actuated and notified, service objects are requested, etc. The details are described in the appropriate manager's type description.

Each manager type has an associated component metadata type. Component Metadata is used to configure a manager. XML definition resources in the bundle define the source for this Metadata. In the previous example, the service and bean XML element are translated to a ServiceMetadata and BeanMetadata object respectively.

The Blueprint Container maintains a registry of managers by their id. These are the managers that are called the top-level managers. Top level managers are managers defined as child elements of the top XML blueprint element or bean managers in the type-converters element. Their Metadata is registered under their id (or calculated id) in the Blueprint Container. All top level managers share a single namespace. That is, it is an error if the same id is used multiple times or attempts to override the built-in environment managers.

Top level managers can depend on other top level managers but there are many places where a manager can depend on an inlined manager. In these places, a complete manager can be defined inside another manager. Such inlined managers are always anonymous: they must not have an id and must not be registered as a top-level manager. Inlined beans are further constrained to always have prototype scope. That is, every time they are asked to provide a component instance, they must return a different object.

When the Blueprint Container must be destroyed, all singleton component instances that have been created must be destroyed. This must first deactivate all activated managers. All these managers must release their dependencies on any component instances they hold. Then the Blueprint Container must destroy all singleton component instances. The order of this destruction must be such that a component instance is only destroyed if there are no other component instances depending on it. See Reverse Dependency Order.

The relations between manager types, component instances, metadata and the Blueprint Container is schematically depicted in Figure 121.2 on page .

Figure 121.2 Managers and Metadata

Managers and Metadata

121.2.1 Manager Types

Blueprint only supports a fixed set of the following manager types:

  • Bean - A bean manager provides regular Java objects as component instances. It has the following features:

    • Construction via class name, static factory method, or a factory method on a target. A target is a reference to a top level manager of type bean or service reference, or a referral to a top level manager of those types.

    • Can have arguments for a constructor or factory method.

    • Can have properties that are injected.

    • Manages a singleton or creates objects on demand depending on its scope.

    • Life cycle callbacks for end of initialization and destruction.

    See Bean Manager for more details.

  • Reference - Reference managers track a service in the OSGi service registry. When activated, they provide a proxy to a service object. See Service Reference Managers for more details. A reference is satisfied when its selection matches a service in the registry.

  • Reference-list - Reference-list managers track multiple services. A reference-list is satisfied when its selection matches one or more services in the registry. See Service Reference Managers for more details.

  • Service - Service managers maintain the registration of an OSGi service object. Service managers provide a proxied ServiceRegistration object so that the application code has a constant reference, even if the service is unregistered and then registered again. A service manager is enabled if all the mandatory service references in its dependencies are satisfied. See Service Manager.

  • Environment - Environment managers provide access to the environment of the Blueprint bundle, for example its Bundle Context. See Blueprint Container for more details.

121.2.2 Metadata Objects

Metadata objects hold the configuration information (from the Component Definition) for the managers. These metadata objects represent the element structure found in the XML definitions in canonical form. Each element in the XML has a corresponding Metadata sub-type that has a name that maps directly to the element. For example, the bean element represents the bean manager that has its configuration data defined in the BeanMetadata interface.

There are Metadata interfaces for all the manager types, except the environment type. Some dependency injections require the construction of arrays, maps, properties, simple objects, etc. For these type of objects, additional Metadata sub-interfaces are defined; these interfaces provide the information to construct the basic programming types. For example, the CollectionMetadata interface contains the information to construct an Array or Collection of a given type, where its member values are defined by other Metadata objects.

The set of Metadata types is fixed in this specification, just like the set of manager types. It is impossible to extend this set with user defined Metadata types. For more information about Metadata, see Metadata.

121.2.3 Activation and Deactivation

Managers are created after all the definitions are parsed. Some managers can already show some activity, for example service managers always activate explicit dependencies and register a Service Factory with the OSGi service registry. However, in this state a manager should attempt to not use any resources from the Blueprint bundle until it is activated itself.

A manager must be atomically activated when it has to provide its first component instance. During activation it can perform a manager specific initialization that will actually consume resources from the Blueprint bundle. This activation must be atomic. That is, if a manager is being activated then other threads must block until the activation is completed.

Deactivation only happens during the destruction of the Blueprint Container. During deactivation, a manager must release any dependencies on resources of the Blueprint bundle. No components instances are destroyed during deactivation because the singleton component instance destruction must happen after all managers are deactivated.

Each manager type has a dedicated section that describes what must happen during its activation and deactivation.

121.2.4 Manager Dependencies

Managers that refer to other managers depend on these managers transitively. For example, a service manager depends directly on the manager that provides the service object. In its turn, that service object could depend on any provided objects that were used to construct and inject this service object, and so on. This transitive set of dependencies are called implicit dependencies because these dependencies are implicitly created by the use of other managers in the Component Definitions.

Managers can also be configured with explicit dependencies. The XML definitions for all managers have a depends-on attribute with a whitespace delimited list of manager ids. Each of these depends-on managers must provide an object, that will be ignored. The timing of activation of dependencies depends on the specific managers but in general should happen before any observable behavior.

There is no ordering guarantee between independent sets of dependencies. The dependency graph is based on the managers, not the component instances. For example, the following definition:

<blueprint default-activation='eager'>
  <bean id='A'...>  <argument ref='B'> </bean>
  <bean id='B' depends-on='C E'...>  
    <argument ref='C'> 
  </bean>
  <bean id='C' scope='prototype' ...>  
    <argument ref='D'> 
  </bean>
  <bean id='D' .../>
  <bean id='E' ...> <argument ref='C'/> </bean>
  <bean id='F' depends-on='B' activation="lazy"/>
</blueprint>

After initialization, there will be the following component instances: a, b, d, e, and three c's. Lower case names are used for instances, the corresponding upper case is its manager. The ordering guarantee is that manager D is activated before manager C, manager C is activated before manager E and B, manager E is activated before manager B, and manager B is activated before manager A. There will be no component instance f created because F is a lazy manager. There are three c's because manager E and B have an implicit dependency on C and manager B has an additional explicit dependency, totaling 3 dependencies. One of these c's is an orphan and will be garbage collected over time because it is not referred to by any component instance.

The example is depicted in Figure 121.3 on page .

Figure 121.3 Dependency Graph after initialization

Dependency Graph after initialization

121.2.5 Reverse Dependency Order

The destruction of component instances must be done in reverse dependency order. This concept is defined as only destroying a singleton component instance (in a manager specific way) when no other activated singleton component instance has an implicit or explicit dependency on it. That is, a component instance has no more field references to other component instances. A component that never was activated does not have any dependencies.

This strategy will ensure that a component instance cannot have an instance field that refers to an component instance that has been destroyed.

Deactivating the manager will release its dependencies, which then frees up other component instances until all component instances are destroyed, or there are cyclic references. In the case of cyclic dependencies, the order of destruction is undefined.

In the example depicted in Figure 121.3 on page , the previous rules imply that component instance a can be immediately destroyed first because it has no clients. After component instance a is destroyed, component instance b becomes free because no other component instances refer to it. The explicit dependency from manager F to manager B was never activated, so it is not taken into account. The destruction of component instance b frees up component instance e and c because now the explicit dependency from manager B to manager E and manager B to manager C have been released. Manager C is deactivated but no component instances are destructed because it has prototype scope; these managers do not destroy their component instances. Then component instance d can be destructed.

121.2.6 Cyclic Dependencies

The implicit and explicit dependencies of a component form a dependency graph. In the ideal case, this graph should be free from cycles. A cycle occurs when a set of one or more managers find themselves in their own implicit or explicit dependencies. For example:

public class A { public A(B b); }
public class B { public void setA(A a); }

<bean id="a" class="A"> <argument ref="b"/> </bean>
<bean id="b" class="B"> <property name="a" ref="a"/> </bean>

In this example, the cycle is the set {a,b}. Managers can be part of multiple cycles.

When a member of a cycle is requested to provide a component instance, the Blueprint Container must break the cycle by finding one breaking member in the cycle's members. A breaking member must be a singleton bean and use property injection for the dependency that causes the cycle. The Blueprint Container can pick any suitable member of the cycle for breaking member, if no such member can be found, then initialization fails or the getComponentInstance method must throw a Component Definition Exception.

In the previous example, manager b can be a breaking member because it uses the property injection for the cyclic dependency on manager a. Manager a cannot be a breaking member because the cyclic dependency is caused by a constructor argument, a breaking member must use property injection for the cyclic dependency to be broken.

A breaking member must return a partially initialized component instance when it is asked to provide an object. A partially initialized object has done all possible initialization but has not yet been called with the initMethod (if specified) nor has it been injected any of the properties that causes a cycle. The finalization of the partially initialized component instance must be delayed until the breaking member has been injected in all referring members of the cycles. Finalization means injecting any remaining unset properties and calling of the initMethod, if specified.

The consequence of partially initialized component instances is that they can be used before they have all properties set, applications must be aware of this.

All partially initialized component instances must be finalized before the Blueprint Container enters the Runtime phase and before a call to the getComponentInstance method returns a component instance.

All detected cycles should be logged.

Consider the following example:

public class A {
 public A(B b) {}
}
public class B {
 public B(A a) {}
}

And the configuration:

<bean id="a" class="A"> <argument ref="b"/> </bean>
<bean id="b" class="B"> <argument ref="a"/> </bean>

In this case, the cycle cannot be broken because neither manager qualifies as breaking manager because they have a constructor/factory argument dependency. That is, it is impossible to construct an object without using the dependency. However, consider the following example:

public class A {
 public A(B b) {}
}
public class B {
 public B(C c) {}
}
public class C {
  public void setA(A a) {}
}

And the configuration:

<bean id="a" class="A"> <argument ref="b"/> </bean>
<bean id="b" class="B"> <argument ref="c"/> </bean>
<bean id="c" class="C" init-method="done"> 
    <property name="a" ref="a"/>      
</bean>

This configuration is depicted in Figure 121.4 on page . This cycle {a,b,c} can be broken by selecting manager c as the breaking member. If manager a is requested to provide a component instance for the first time, then the following sequence takes place:

activate a
  activate b
    activate c
      c = new C()
    b = new B(c)
  a = new A(b)
  c.seta(a)
  c.done()
return a

Figure 121.4 Cyclic Dependency

Cyclic Dependency

Cycles must be broken, if possible, both for singleton managers as well as prototype beans, although a breaking manager must always be a singleton bean because a prototype bean must always return a new object, making it impossible to break the cycle by returning a partially initialized component instance. That is, the following definition is not allowed to attempt to create an infinite loop:

<bean id="a" scope="singleton" class="A"> 
  <property name="a" ref="a">
</bean>

The previous definition must create an A object that refers to itself. However, if the example had used a prototype scope, it would be an unbreakable cycle.

121.2.7 Eager Managers

The Blueprint Container can force the activation of the application in the Blueprint bundle with eager managers. An eager manager is a manager that has the activation set to eager. A bean manager can only be eager if it has singleton scope.

Eager managers are explicitly activated by asking them to provide a component instance after all other initialization is done. A bundle that wants to be lazily initialized should not define any eager managers.

121.3 Blueprint Life-Cycle

A bundle is a Blueprint bundle if it contains one or more blueprint XML definition resources in the OSGI-INF/blueprint directory or it contains the Bundle-Blueprint manifest header referring to existing resources.

A Blueprint extender is an implementation of this specification and must track blueprint bundles that are type compatible for the Blueprint packages and initialize them appropriately. The timing and ordering of the initialization process is detailed in the following section.

There should be only one Blueprint extender present in an OSGi framework because this specification does not specify a way to resolve the conflicts that arise when two Blueprint extenders extend the same Blueprint bundle.

121.3.1 Class Space Compatibility

A Blueprint extender must not manage a Blueprint bundle if there is a class space incompatibility for the org.osgi.service.blueprint packages. For example, if the Blueprint bundle uses the BlueprintContainer class, then it must import the org.osgi.service.blueprint.container package. The Blueprint extender and the Blueprint bundle must then share the same class space for this package. Type compatibility can be verified by loading a class from the blueprint packages via the Blueprint extender bundle and the Blueprint bundle's loadClass methods. If the Blueprint bundle cannot load the class or the class is identical to the class loaded from the extender, then the two bundles are compatible for the given package. If the Blueprint extender is not class space compatible with the Blueprint bundle, then Blueprint extender must not start to manage the Blueprint bundle.

121.3.2 Initialization of a Blueprint Container

A Blueprint extender manages the application life cycle of Blueprint bundles based on:

  • The Blueprint bundle state,

  • The Blueprint definitions,

  • The Blueprint extender's bundle state

  • The class space compatibility

All activities on behalf of the Blueprint bundle must use the Bundle Context of the Blueprint bundle. All dynamic class loads must use the Blueprint bundle's Bundle loadClass method.

The following sections describe a linear process that handles one Blueprint bundle as if it was managed by a special thread, that is, waits are specified if the thread waits. Implementations are likely to use a state machine instead for each managed Blueprint bundle, the linear description is only used for simplicity.

In the following description of the initialization steps, the Blueprint Container will update its state. State changes are broadcast as events, see Events.

If any failure occurs during initialization, or the Blueprint bundle or Blueprint extender bundle is stopped, the Blueprint Container must be destroyed, see Failure. These checks are not indicated in the normal flow for clarity.

121.3.2.1 Initialization Steps

The initialization process of a Blueprint Container is defined in the following steps:

  1. Wait until a blueprint bundle is ready. A blueprint bundle is ready when it is in the ACTIVE state, and for blueprint bundles that have a lazy activation policy, also in the STARTING state.

  2. Prepare, verify if this Blueprint bundle must be managed, see Preparing.

  3. State = CREATING

  4. Parse the XML definition resources.

  5. Service reference managers must start tracking their satisfiability without actually activating. See Tracking References.

  6. If all mandatory service references are satisfied, or the blueprint.graceperiod is false, then go to step 9.

  7. State = GRACE_PERIOD

  8. Perform the grace period. This period waits until all mandatory service references are satisfied. See Grace Period. This step fails if the mandatory dependencies are not satisfied at the end of the grace period.

  9. The Blueprint Container is now ready to provide component instances.

  10. Service managers must initialize their explicit dependencies and have a Service Factory registered during the periods that they are enabled. See Service Registration.

  11. Ask all eager managers to provide a component instance. See Eager Instantiation.

  12. State = CREATED

  13. Register the Blueprint Container

  14. The components are now active and perform their function until the Blueprint bundle or the Blueprint extender bundle are stopped.

  15. State = DESTROYING

  16. Perform the Destroy phase, see Destroy the Blueprint Container.

  17. State = DESTROYED

121.3.2.2 Failure

If at any time there is a failure, the Blueprint Container must:

  1. State = FAILURE

  2. Unregister the Blueprint Container service.

  3. Destroy the Blueprint Container.

  4. Wait for the Blueprint bundle to be stopped.

121.3.2.3 Diagram

This initialization process is depicted in Figure 121.5 on page .

Figure 121.5 Blueprint Bundle Initialization

Blueprint Bundle Initialization

121.3.3 Extensions

A compliant implementation of this specification must follow the rules as outlined. However, implementations can provide functional extensions by including attributes or elements of other namespaces. For example, a Blueprint extender implementation that supports proxying of certain classes and a number of additional type converters could include a http://www.acme.com/extensions namespace that adds an extensions attribute on the blueprint element:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint
 xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
 xmlns:ext="http://www.acme.com/extensions"

  ext:extensions="proxyClasses"
>
  ...
</blueprint>

Blueprint extenders that detect the use of an unrecognized namespace must fail to signal a portability problem.

121.3.4 Preparing

Blueprint definitions are stored as resources in the Blueprint bundle. If a Bundle-Blueprint manifest header is defined, then this header contains a list of paths. The Bundle-Blueprint header has the following syntax:

Bundle-Blueprint ::= header 
                     // See Common Header Syntax in Core

This specification does not define any attributes or directives for this header. Implementations can provide proprietary parameters that should be registered with the OSGi Alliance to prevent name collisions. The non-localized version of the header must be used.

The last component of each path in the Bundle-Blueprint header may use wildcards so that Bundle.findEntries can be used to locate the XML document within the bundle and its fragments. The findEndtries method must always be used in the non-recursive mode. Valid paths in the header have one of the following forms:

  • absolute path - The path to a resource in the fragment or directory, this resource must exist. For example cnf/start.xml.

  • directory - The path to directory in a fragment or main bundle, the path must end in a solidus ('/' \u002F). The pattern used in the findEntries method must then be *.xml. The directory is allowed to be empty.

  • pattern - The last component of the path specifies a filename with optional wildcards. The part before is the path of directory in the bundle or one of its fragments. These two parts specify the parameter to findEntries. It is allowed to have no matching resources. An example of a pattern is: cnf/*.xml.

If no resources can be found, then the Blueprint bundle will not be managed and the initialization exits.

For example, the following header will read the resources /lib/account.xml, /security.bp, and all resources which path ends in .xml in the /cnf directory:

Bundle-Blueprint: lib/account.xml, security.bp,cnf/*.xml

If the Bundle-Blueprint header is not defined, then its default value is:

OSGI-INF/blueprint/*.xml

A Bundle-Blueprint manifest header specified in a fragment is ignored by the Blueprint Container. However, XML documents referenced by a bundle's Bundle-Blueprint manifest header, or its default, may be contained in attached fragments, as defined by the findEntries method.

If the Bundle-Blueprint header is specified but empty, then the Blueprint bundle must not be managed. This can be used to temporarily disable a Blueprint bundle.

121.3.5 Parsing

The Blueprint Container must parse the XML definitions into the Blueprint Container's metadata registry. Parsing fails if:

  • A path from the Bundle-Blueprint header cannot be found in the bundle or any of its fragments.

  • An XML definition does not validate against its schema.

  • The XML elements do not meet one or more of their constraints

  • Any errors occur

For failure, see Failure.

121.3.6 Tracking References

Service reference managers must track the service registry to see if they are satisfied or not. These managers must not be activated to register these service listeners nor must they activate any dependencies until they are activated. That is, no component instances for the reference listeners are obtained until the service reference manager is activated.

121.3.7 Grace Period

A Blueprint Container by default will wait for its dependencies in the grace period. However, this can be overridden with a directive on the Bundle-SymbolicName header of the Blueprint bundle:

  • blueprint.graceperiod ( true|false) - If set to true, then the Blueprint Container must enter the grace period and wait for dependencies, this is the default. Otherwise, it must skip the grace period and progress to the next phase regardless if there are any unsatisfied service references.

The purpose of the grace period is to handle the initialization of multiple bundles gracefully. The grace period will first wait a configurable time for all mandatory service references to become satisfied, or for the bundle to stop. If these mandatory services are satisfied, then the grace period succeeds, otherwise it will fail. If the bundle is stopped during the grace period, then the Blueprint Container must be destroyed.

During the waiting period services can come and go. Each time such a service event takes place that involves any of the mandatory service references, the Blueprint Container must send out another GRACE_PERIOD event if that event does not result in ending the grace period. The event contains the complete filters of the unsatisfied service references, see Blueprint Event.

The wait time for the grace period is defined in a directive on the Bundle-SymbolicName header of the Blueprint bundle:

  • blueprint.timeout (Integer >= 0) - The time to wait in the grace period for dependencies to become satisfied in milliseconds. The default is 300000, which is 5 minutes. If the timeout is 0, an indefinite wait will take place.

OSGi services are dynamic, therefore the grace period does not guarantee that all mandatory service references are still available. It only guarantees that at one moment in time they were available. A mandatory reference can become unsatisfied at any moment in time when a service is not available. See the Service Dynamics for a description of how this is handled.

For example, the following header will make the bundle wait a maximum of 10 seconds for its mandatory service references to be satisfied. These dependencies must be satisfied, or a failure occurs.

Bundle-SymbolicName: com.acme.foo;
    blueprint.graceperiod:=true;
    blueprint.timeout:= 10000

121.3.8 Service Registration

A service manager must first activate all its explicit dependencies but it must not activate. It must then ensure that a Service Factory object is registered as a service when that service is enabled. Enabled means that all of the mandatory service references in its dependencies are satisfied.

Once the Service Factory is registered, any bundle can get the corresponding service object. Such a request must activate the service manager, if it is not already activated. Activation of a service manager must obtain a component instance from the Blueprint Container for the service object and any registration listeners. The registration listeners are then actuated and notified of the initial state.

121.3.9 Eager Instantiation

After all initialization is done, the Blueprint Container is ready. It is now possible to request component instances. If a bundle needs immediate startup because they cannot wait until they are triggered, then it should set the activation of its bean managers to eager. The Blueprint Container must request all eager managers to provide a component instance in this instantiation phase, see also Lazy and Eager.

121.3.10 Runtime Phase

The Blueprint Container must be registered as a service with the following service properties:

  • osgi.blueprint.container.symbolicname - The bundle symbolic name of the Blueprint bundle

  • osgi.blueprint.container.version - The version of the Blueprint bundle

The Blueprint Container service must only be available during the runtime phase when initialization has succeeded.

As long as the Blueprint extender and the Blueprint bundle are active, the application is in the runtime phase. The component instances perform their requested functionality in collaboration. The Blueprint Container can be used to provide objects from the defined managers, get information about the configuration, and general state information, see Blueprint Container.

121.3.11 Destroy the Blueprint Container

The Blueprint Container must be destroyed when any of the following conditions becomes true:

  • The Blueprint bundle is stopped, that is, it is no longer ready.

  • The Blueprint extender is stopped

  • One of the initialization phases failed.

Destroying the Blueprint Container must occur synchronously with the Bundle STOPPING event if that caused any of the previous conditions. For example, if the Blueprint extender is stopped, it must synchronously destroy all Blueprint Containers it has created.

Destroying the Blueprint Container means:

  1. Unregistering the Blueprint Container service

  2. Deactivating all managers.

  3. Destroying all component instances in reverse dependency order, see Reverse Dependency Order.

A Blueprint Container must continue to follow the destruction even when component instances throw exceptions or other problems occur. These errors should be logged.

If the Blueprint extender is stopped, then all its active Blueprint Containers must be destroyed in an orderly fashion, synchronously with the stopping of the Blueprint extender bundle. Blueprint Containers must use the following algorithm to destroy multiple Blueprint Containers:

  1. Destroy Blueprint Containers that do not have any services registered that are in use by other bundles. More recently installed bundles must be destroyed before later installed bundles, that is, reverse bundle id order.

  2. The previous step can have released services, therefore, repeat step 1 until no more Blueprint Containers can be destroyed.

  3. If there are still Blueprint Containers that are not destroyed, then destroy the Blueprint Container with:

    • The registered service that is in use with the lowest ranking number, or if a tie

    • The highest registered service id

    If there are still Bundle Containers to be destroyed, retry step 1

During the shutting down of an OSGi framework, it is likely that many bundles are stopped near simultaneously. The Blueprint extender should be able to handle this case, without deadlock, when the stop of a Blueprint bundle overlaps with the stop of the Blueprint extender bundle.

121.3.12 Failure

If a failure occurs during the initialization of the Blueprint bundle, then first a FAILURE event must be posted, see Events. Then the Blueprint Container should be destroyed, ensuring that no uninitialized or half initialized objects are destroyed. Failures should be logged if a Log Service is present.

121.3.13 Lazy

The Blueprint Container specification specifically allows lazy initialization of the application in the Blueprint bundle. No component instances are created until an eager manager is activated, or a service request comes in.

If no eager managers are defined and no service has explicit dependencies, then no component instances are provided until an external trigger occurs. This trigger can be a service request or a call to the getComponentInstance method of the Blueprint Container, which is registered as a service. This allows a Blueprint bundle to not create component instances, and thereby load classes, until they are really needed. This can significantly reduce startup time.

Some features of the component definitions can only be verified by inspecting a class. This class loading can break the lazy initialization of a Blueprint bundle. It is therefore allowed to delay this kind of verification until the activation of a manager.

This lazy behavior is independent of the bundle's lazy activation policy. Though the Blueprint extender recognizes this policy to detect when the bundle is ready (for a lazy activated bundle the STARTING state is like the ACTIVE state), it is further ignored. That is, the relation between a Bundle Activator that is lazily activated and the Blueprint Container is not defined.

121.4 Blueprint Definitions

The Blueprint XML resources in a bundle are the definitions. Each definition can include multiple namespaces. Implementations of the Blueprint core namespace must strictly follow this specification, if they add additional behavior they must add additional namespaces that are actually used in the definitions to signal the deviation from this specification.

The namespace for the core Blueprint definition resources is:

http://www.osgi.org/xmlns/blueprint/v1.0.0

Blueprint resources that use this core specification must have as top the blueprint element. The following example shows the body of a Blueprint definition:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint
 xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
  ...
</blueprint>

The recommended prefix for the Blueprint core namespace is bp.

All elements in the Blueprint namespace are prepared for future extensions and provide a description child element in most positions.

121.4.1 XML

In the following sections, the XML is explained using the normal syntax notation used for headers. There is, however, one addition to the normal usage specific to XML, and that is the use of the angled brackets ( <>). A term enclosed in angled brackets, indicates the use of a real element. Without the angled brackets it is the definition of a term that is expanded later to a one or more other terms or elements. For example:

people     ::= <person> *
person     ::= <child>* address
address    ::= <fr> | <us> | <nl>

Describes for example the following XML:

<people>
    <person id="mieke">
        <child name="mischa"/>
        <child name="thomas"/>
        <fr zip="34160"/>
    </person>
</people>

Attributes are described in tables that define how they map to their corresponding Metadata. As a rule, the XML elements and attributes are expressed directly in the Metadata.

The text in the following sections is a normative description of the semantics of the schema. However, the structure information is illustrative. For example, all description elements have been ignored for brevity. The exact structure is described by the XML schema, see Blueprint XML Schema.

There are a number of convenient XML types used in the following sections. There schema types are defined here:

  • qname - A fully qualified Java class name in dotted form, for example java.lang.String.

  • method - A valid Java method name, for example setFoo.

  • NCName - A string syntax for names defined in [8] XML Schema.

  • ID - A string syntax for ids defined in [8] XML Schema.

  • type - A name of a Java type including arrays, see the next section Syntax for Java types.

  • target - An inline bean, reference, or ref, see Target.

  • object - An object value, see Object Values

In several cases, the actual syntax depends on the type conversion. This type of syntax is indicated with <<type>> indicates that the syntax of the string depends on the type conversion, where ten type is usually given as a parameter on the same Metadata.

121.4.2 Syntax for Java types

A number of elements can refer to a Java type, for example the value element has a type attribute and a map element has a key-type attribute. The syntax for these types is as follows:

type    ::= qname array
array   ::= '[]' *

Where qname is the fully qualified name of a Java class or interface, or the name of a primitive type.

For example:

<value type="java.lang.String[]"/>

It is not possible to specify generic information in this syntax.

121.4.3 XML and Metadata

The Blueprint Container parses the XML into Metadata objects, see Metadata. During parsing, the XML parser validates against the detailed Blueprint schema and will therefore catch many errors. However, the XML schema and the Metadata type are not equivalent. The XML contains many conveniences that the Blueprint Container must convert to the canonical type in the Metadata. A number of general rules apply for this conversion:

  • An absent attribute will result in null, unless the schema element provides a default value. In that case, the default must be returned from the Metadata object. That is, a default is indistinguishable from a specifically set value.

  • Defaults from the blueprint element are filled in the Metadata objects, they are not available in any other way.

  • Strings are trimmed from extraneous whitespace, as described in XML normalization.

  • Child elements are represented by List objects, in the order of their definition. If no child elements are specified, the list will be empty.

For example, the activation feature reflects the total of default-activation and activation attributes but does not reflect that a prototype scope always makes a bean lazy. That is, even if activation is eager, the bean must still have lazy activation when it has prototype scope.

121.4.4 <blueprint>

The blueprint element is the top element. The definitions consist of two sections: the type-converter section and the managers section.

blueprint           ::= <type-converters>manager*
manager             ::= <bean> | <service>  
                               | service-reference
service-reference   ::= <reference> | <reference-list>
type-converters     ::= <bean> | <ref>

In this specification, the reference and reference-list managers are referred to as service references when their differences are irrelevant. The blueprint element structure is visualized in Figure 121.6.

Figure 121.6 Managers (bold = element name, plain=base type)

Managers (bold = element name, plain=base type)

121.4.5 Metadata

The blueprint element has no corresponding Metadata class.

121.4.6 Defaults

The blueprint element supports the setting of the diverse defaults for the current definition resource with the following attributes:

  • default-activation - Controls the default for the activation attribute on a manager. See Lazy and Eager. The default for this attribute is eager.

  • default-availability - The default availability of the service reference elements, see Service Reference Managers. The default for this attribute is mandatory.

  • default-timeout - The default for the reference element timeout attribute, see Service Reference Managers. The default for this attribute is 30000, or 5 minutes.

These defaults are specific for one definition resource, they apply only to elements enclosed to any depth in the blueprint element. These defaults are not visible in the Metadata.

121.4.7 <type-converters>

The Blueprint definitions are text based but the component instances require actual classes for their construction and dependency injection. Component instances are injected with general objects the target type is not always compatible with the source type. This specification therefore allows for type conversion. Type conversion rules are specified in Type Conversion. This section provides beans, or referrals to beans, that can be used in this type conversion process. They are listed in a separate section so they can be registered as a type converter, pre-instantiated, and preventing dependencies that easily become cyclic. Beans defined in the type-converters element must be registered as top-level managers.

The structure of the type-converters element is:

type-converters     ::= ( <bean> | <ref> )*

Type converters defined with the ref element can refer to bean managers or reference managers. Type converters must have ids distinct from any other manager and are available through the Blueprint Container's getComponentInstance method.

121.4.8 manager

The component XML schema type is the base type of the bean, service, reference-list, and reference elements. All manager sub-types share the following attributes:

  • id - The manager and its Metadata are identified by its id as defined in its Component Definition. In general this id is therefore referred to as the component id. This is an optional attribute. If it is not defined, a default calculated unique id will be assigned to it for top-level managers. For inlined managers, the id attribute cannot be set, their Metadata must return null. All top level manager ids must be unique in a Blueprint Container.

    The id attribute must be of type ID as defined in XML Schema, see [8] XML Schema. The syntax for an id is therefore:

    id  ::=     ID              // See ID in [8] XML Schema

    Ids generally use camel case, like myComponent, and they are case sensitive. That is, component id madHatter and madhatter are distinct ids. Applications should not use ids starting with the prefix blueprint.

    Ids are not required, if no component id is specified, the Blueprint Container must assign a unique id when it is a configured in a top level element. This calculated id must start with a full stop ('.' \u002E).

The Metadata interface of top level managers will be a sub-interface of ComponentMetadata and is available from the Blueprint Container by its component id.

Figure 121.7 Inheritance hierarchy for managers

Inheritance hierarchy for managers

121.4.9 Explicit Dependencies

The dependsOn list contains the ids of the top-level managers the bean explicitly depends on. Unless stated otherwise in the specific manager description, explicit dependencies must be activated before their manager is activated.

For example:

<bean id="alice" class="com.acme.MadHatter" 
        depends-on="cheshire rabbit queen"/>

This example will ask the top level managers cheshire, rabbit, and queen to provide an object before alice is activated. For a discussion about dependencies see Manager Dependencies.

121.4.10 Lazy and Eager

During initialization, all eager top level managers are requested to provide a component instance. Applications can use this request as an indication to start providing their intended functionality.

Managers that are lazy, that is, not singleton scope, activation is lazy, or inlined, are activated when they are first asked to provide a component instance. Therefore, even lazy managers can activate during initialization when they happen to be a dependency of another manager that activates its dependencies.

Services and service references can also have lazy or eager activation. The eager activation will ensure that all listeners are properly actuated during the corresponding activation. For services, the service object is then also requested at startup.

The following example defines an eager bean by making it a singleton and setting the activation to eager:

<bean id="eager" scope="singleton"
        class="com.acme.FooImpl" activation="eager"/>

121.4.11 Target

In several places in the Blueprint schema it is necessary to refer to a target. A target is a:

  • ref - Must reference one of the following managers

  • reference - An inlined reference manager

  • bean - An inlined bean manager

The target type is normally used for listeners, service objects, and other places where a general application component instance is required.

121.5 Bean Manager

A bean manager provides an arbitrary Java object. It constructs this object from a given class or factory and then configures the object by injecting its properties with other component instances or more general object values.

The provided component instance can be a singleton or a new object can be returned on every invocation (prototype), this behavior is defined with the scope attribute, see Scope.

The provided object can optionally be notified when all of its properties have been injected, and when the providing bean manager will be deactivated, see Life Cycle Callbacks.

121.5.1 Bean Component XML

The structure of a bean element is:

bean    ::= ( <argument> | <property>)*

Figure 121.8 Bean Structure

Bean Structure

121.5.2 <bean>

The Metadata for a bean manager is represented in the BeanMetadata interface, which extends ComponentMetadata. Table 121.1 provides an overview of the related XML definitions and the BeanMetadata interface. The table only provides a summary, the sometimes subtle interactions between the different features are discussed in later sections.

Table 121.1 Bean Manager Features

Attribute or Element Syntax Bean Metadata Description
id ID

id

: String

The id of a top level manager, must be unique in the Blueprint Container. All inlined managers must return null for their id.

activation

  lazy

| eager

activation

: int

Defines if this bean is lazily or eagerly activated. If not explicitly set, the blueprint element's value for the default-activation attributes is used. If this is also not set, the value is eager. See Lazy and Eager.

depends-on NCName*

dependsOn

: List<String>

Explicit list of ids that are the dependencies. These referred managers must be activated before this bean can provide an object. See Explicit Dependencies. This is a whitespace separated list.

class qname

className

: String

Class name of the object to be provided or the class name for a static factory. See Construction.

scope

  singleton

| prototype

scope

: String

The scope defines the construction strategy for the component instance. The default is singleton except for inlined bean managers, where it is prototype. There is no schema default, so if it is not explicitly set, the Metadata will be null. See Scope.

init-method method

initMethod

: String

The name of a method to invoke when a provided object has been injected with all its properties. If this is not set, it is null. See Life Cycle Callbacks.

destroy-method method

destroyMethod

: String

A name of a method to invoke on the provided objects with singleton scope when the Blueprint Container is destroyed. If this is not set, it is null. See Life Cycle Callbacks.

factory-method method

factoryMethod

: String

The name of the method on a static or component instance factory. See Construction.

factory-ref NCName

factoryComponent

: String

A reference to a manager that acts as the factory. See Construction.

<argument> Table

arguments

: List<BeanArgument>

Defined as sub-elements of the bean element. A BeanArgument object contains the value of an argument in the factory method or constructor. The order of the arguments is declaration order. See Construction.

<property> Table

properties

: List<BeanProperties>

Defined as sub-elements of the bean element. A BeanProperty object provides the property name and injection value. See Properties.


The bean element has the following constraints that are not enforced by the schema but must be enforced by the Blueprint Container:

  • The destroyMethod must not be set when the scope is prototype.

  • The activation must not be set to eager if the bean also has prototype scope.

  • The following combinations of arguments are valid, all other combinations are invalid:

    • className

    • className, factory-method

    • factory-ref, factory-method

121.5.3 <argument>

The argument element holds a value for a constructor or factory method's parameters.

Table 121.2 Bean Argument Features

Attribute or Element Syntax Bean Argument Description
index int >= 0

index

: int

The index of the argument in the constructor or factory-method signature. If this is not set, the Blueprint Container must use the type information to calculate it to match the disambiguation algorithm. The index will be -1 when not explicitly set.

type qname

valueType

: String

The fully qualified class name of a Java type to match the argument to the signature against.

ref NCName

value

: RefMetadata

A reference to a top level manager that provides the value for the argument.

value <<type>>

value

: ValueMetadata

The Value Metadata based on the value property.

<...> object

value

: Metadata

An inlined value.


The argument element has the following additional constraints:

  • Either all arguments have a specified index or none have a specified index.

  • If indexes are specified, they must be unique and run from 0..(n-1), where n is the number of arguments.

  • The following attributes and elements are mutually exclusive:

    • ref

    • value

    • An inlined object value

121.5.4 <property>

The property element holds the information to inject a bean property with an object value.

Table 121.3 Bean Property Features

Attribute or Element Syntax Bean Property Description
name

method

( '.' method

)*

name

: String

The property name, for example foo. The method name can consist of full stop separated method names, indicating nested property access.

ref NCName

value

: RefMetadata

A reference to a top level manager.

value <<type>>

value

: ValueMetadata

A Value Metadata where the type is null.

<...> object

value

: Metadata

An inlined object value.


The argument element has the following additional constraints:

  • The following attributes/elements are mutually exclusive

    • ref

    • value

    • An inlined object value

121.5.5 Scope

A bean manager has a recipe for the construction and injection of an object value. However, there can be different strategies in constructing its component instance, this strategy is reflected in the scope. The following scopes are architected for this specification:

  • singleton - The bean manager only holds a single component instance. This object is created and set when the bean is activated. Subsequent requests must provide the same instance. Singleton is the default scope. It is usually used for core component instances as well as stateless services.

  • prototype - The object is created and configured anew each time the bean is requested to provide a component instance, that is, every call to getComponentInstance must result in a new component instance. This is usually the only possible scope for stateful objects. All inlined beans are always prototype scope.

Implementations can provide additional scope types. However, these types must only be allowed when a defining namespace is included in the definitions and is actually used in the definitions to specify the dependency on this feature.

121.5.6 Construction

The Blueprint specification supports a number of ways for a bean manager to construct an object. Each possibility is a combination of the following Metadata properties:

  • className - Defines the fully qualified name of a class to construct, or the name of a class with a static factory method. The class must be loadable from the Blueprint bundle loadClass method.

  • factoryMethod - A static or instance factory method name that corresponds to a publicly accessible method on the given class or factory manager.

  • factoryComponent - The id of a top-level target manager in the Blueprint Container that is an instance factory.

The Bean manager can have a number of BeanArgument objects that specify arguments for the constructor or for the factory class/object method. The matching constructor or method must be publicly accessible. The argument's valueType can be used to disambiguate between multiple signatures of constructors or methods. See Signature Disambiguation.

The value of the argument is always a Metadata object. Such an object can be converted into a general object value, see Object Values.

The construction properties can be used in a rather large number of combinations, however, not all combinations are valid. Table 121.4 shows the different valid combinations. If none of the combinations matches, then the Bean Metadata is erroneous.

In Table 121.4, a variation of the following bean definition is assumed:

<bean class="C" factory-method="f" factory-ref="fc">
    <argument value="1"/>
    <argument value="2"/>
</bean>

This definition is invalid because it specifies an invalid combination of metadata properties. The only valid combinations are subsets, they are all specified in the following table.

Table 121.4 Component Attributes and Construction

className factory-method factory-ref argument Corresponding Java Code
C       new C
C f     C.f()
C     1,2 new C(1,2)
C f   1,2 C.f(1,2)
  f $fc   $fc.f()
  f $fc 1,2 $fc.f(1,2)
* * * * failure

The object created this way will be the provided object of the bean after any properties are injected. If the factoryMethod returns a primitive type, then this primitive must be converted to the corresponding wrapper type before any usage.

121.5.7 Properties

Dependency injection configures a constructed object with the help of the properties, which is a List of BeanProperty objects. A Bean Property has the following features:

  • name - The name of the bean property. This name refers to the set method on the constructed object as specified in the design pattern for beans getters and setters, see [5] Java Beans Specification. For example, if the property name is foo, then the public method setFoo(arg) will be used to set the value. There should only be one set method with a single argument for a specific property. If overloaded properties are encountered, the chosen set method is unspecified.

    Nested property names are allowed when setting bean properties, as long as all parts of the path, except the property that is set, result in a non-null value. The parts of the path are separated with a full stop ('.' \u002E). For example:

    <property name="foo.bar.baz" value="42"/>

    This example gets the foo property, from the constructed object, it then gets the bar property and then sets the baz property on that object with the given value.

  • value - The value of the property is always a Metadata object. This Metadata object can be converted to a value object, see Object Values.

After the Metadata object is converted to an object value, it must be injected into the property. If the value object is not directly assignable to the property type (as defined by its only set method and the rules in Type Compatibility ), then the Blueprint Container must use the type conversion mechanism to create a new object that matches the desired type, or fail. See Dependency Injection for more information about dependency injection.

For example, the following bean creates an instance and then injects a three into a the foo property that it gets from the bar property. The string that holds the three is converted to a double:

<bean id="foo" class="com.acme.Foo">
  <property name="bar.foo" value="3"/>
</bean>

// Classes
package com.acme;
public class Bar {
    double v;
    public void setFoo(double v) { this.v = v; }
}
public class Foo {
    Bar bar = new Bar();
    public void getBar() { return bar; }
}

// Corresponding Java code
Foo foo = new Foo();
foo.getBar().setFoo(3.0);

121.5.8 Life Cycle Callbacks

The bean element provides two attributes that define the callback method names for initialization and destruction. A callback must be implemented as a publicly accessible method without any arguments. The callback method names must exist as void() methods.

The initMethod specifies the name of an initialization method that is called after all properties have been injected. The destroyMethod specifies the name of a destroy method that is called when the Blueprint Container has destroyed a component instance. Only bean managers with singleton scope support the destroyMethod. The destroy callback cannot be used for beans that have prototype scope, the responsibility for destroying those instances lies with the application.

121.5.9 Activation and Deactivation

A singleton bean manager must construct its single object during activation and then callback its initMethod method. Prototype scoped beans are created after activation and also have their initMethod invoked. The destroy method is called during the destruction of all the beans in singleton scope, this happens after deactivation.

A prototype bean manager has no special activities for deactivation.

121.6 Service Manager

The service manager defined by a service element is responsible for registering a service object with the service registry. It must ensure that this service is only registered when it is enabled. Where enabled means that all its mandatory service reference managers in its dependencies are satisfied.

121.6.1 <service>

The XML structure of the <service> manager is:

service               ::= <interfaces>
                          <service-properties>
                          <registration-listener>*
                          target
interfaces            ::= <value>+
service-properties    ::= <entry>+
registration-listener ::= target

The service manager has the features outlined in Table 121.5 on page . The following additional constraints apply:

  • The interface attribute and interfaces element are mutually exclusive.

  • If the auto-export attribute is set to anything else but disabled, neither the interface attribute nor the interfaces element must be used.

  • The ref attribute and inlined element are mutually exclusive

Table 121.5 Service Manager Features

Attribute or Element Type Service Metadata Description
id ID

id

: String

Optional component id of the manager, if it is a top level manager.

activation

  lazy

| eager

activation

: int

Defines if this service is lazily or eagerly initialized. If not explicitly set, the blueprint element's value for the default-activation attributes is used. If this is also not set, the value is eager. See also Lazy and Eager.

depends-on NCName*

dependsOn

: List<String>

Explicit list of ids that are the dependencies. These managers must be activated at the start of the registration phase. See Explicit Dependencies. This is a whitespace separated list.

interface qname

interfaces

: List<String>

Name of the interface under which this service should be registered. See Service Interfaces.

auto-export

  disabled

| interfaces

| class-

  hierarchy

| all-classes

autoExport

: int

Defines the way the class must be analyzed to find the interfaces under which the service must be registered. The schema default is disabled. See Service Interfaces

ranking int

ranking

: int

The service.ranking value. The schema default is 0, which implies no service property. See Ranking.

ref NCName

value

: RefMetadata

Reference to the manager that provides the service object. See Service Object.

<service-properties> See <map>.

serviceProperties

: List<MapEntry>

The service properties for this service. See Service Properties.

<registration-listener> See Table 121.6.

registrationListeners

: List<Registration

  Listener>

The registration listeners. See Registration Listener.

<interfaces> <value>*

interfaces

: List<String>

Names of interfaces under which this service should be registered. Each interface name must be listed as a child value element. This value element has no attributes. For example:

<interfaces>
 <value>com.a.Foo</value>
 <value>com.a.Bar</value>
</interfaces>

The value element must only hold a string value. See Service Interfaces

<...> target

value

: Target

An inlined target manager that is used for the service object. See Service Object


121.6.2 <registration-listener>

The service element can contain zero or more registration-listener elements, that define registration listeners to be notified of service registration and unregistration events. This element has the following structure:

registration-listener   ::= target*

The registration-listener element defines the callback methods for registration and unregistration.

Table 121.6 Registration Listener Features

Attribute or Element Type Registration Listener Description
ref NCName

registrationListener

: Target

A reference to a top level manager.

registration-method method

registrationMethod

: String

The name of the method to call after the service has been registered. See Registration Listener.

unregistration-method method

unregistrationMethod

: String

The name of the method to call before the service will be unregistered. See Registration Listener.

<...> target

registrationListener

: Target

An inlined target manager


The additional constraint is:

  • The ref attribute and the inlined manager are mutually exclusive.

  • Either or both of the registrationMethod and unregistrationMethod must be set.

  • For each method name set, there must be at least one method matching the possible prototypes in the registration listener object, see Registration Listener.

121.6.3 Explicit Dependencies

A service manager must initialize any explicit dependencies in the start of its registration phase, even before it tracks its enabled state. The presence of explicit dependencies will not activate the service manager.

121.6.4 Provided Object

A service manager provides a proxy to a ServiceRegistration object. If this proxy is used when the dependencies are not met, and the service is therefore unregistered, an Illegal State Exception must be thrown. In all other cases, the proxy acts as if it was the ServiceRegistration object associated with the registration of its service object.

The unregister method on the returned object must not be used. If the application code calls unregister then this must result in an Unsupported Operation Exception.

121.6.5 Service Interfaces

Each service object is registered under one or more interface names. The list of interface names is provided by interfaces or autoExport.

The autoExport tells the Blueprint Container to calculate the interface(s) from the type of the service object. The autoExport can have the following values:

  • disabled - No auto-detection of service interface names is undertaken, the interface names must be found in interfaces. This is the default mode.

  • interfaces - The service object will be registered using all of its implemented public Java interface types, including any interfaces implemented by super classes.

  • class-hierarchy - The service object will be registered using its actual type and any public super-types up to the Object class (not included).

  • all-classes - The service object will be registered using its actual type, all public super-types up to the Object class (not including), as well as all public interfaces implemented by the service object and any of its super classes.

The autoExport requires the actual class object for introspection for all its modes except disabled,which can cause a bundle with a lazy activation policy to activate because a class will be loaded from the Blueprint bundle.

As an example:

<bean id="fooImpl" class="FooImpl"/>

public class FooImpl implements Foo { ... }

Then the following service definitions are equivalent:

<service id="foo">
    <interfaces>
        <value>com.acme.Foo</value>
    </interface>
</service>
<service id="foo" interface="com.acme.Foo" ref="fooImpl"/>
<service id="foo" auto-export="interfaces" ref="fooImpl"/>

121.6.6 Service Properties

Each service can optionally be registered with service properties. The serviceProperties is a list of MapEntry, see <entry>. This metadata must be used to create the service properties. Service properties creation can have side effects because they can use component instances. The service properties must therefore be created once before the first time the first time the service is registered.

The service manager adds the following automatic service properties that cannot be overridden. When these properties are explicitly set, they must be ignored.

  • osgi.service.blueprint.compname - This will reflect the id of the manager that provides the service object, unless it is inlined. Inlined beans are always anonymous and must not have this property set.

  • service.ranking - If the ranking attribute is not zero, this property will be set and hold an Integer object with the given value, see Ranking.

For example, the following definition is followed by equivalent Java code needed to register the service:

<service ref="fooImpl" interface="com.acme.Foo">
  <service-properties>
    <entry key="size" value="42"/>
  </service-properties>
</service>

Dictionary d = new Hashtable();
d.put("size", "42");
d.put("osgi.service.blueprint.compname", "fooImpl");
ServiceRegistration sr = 
    bundleContext.registerService("com.acme.Foo",
        blueprintContainer.getComponentInstance("fooImpl"),
      d);

Service properties should specify the valueType of the entry unless the value to be registered needs to be a String object. The service property types should be one of:

  • Primitives Number - int, long, float, double, byte, short, char, boolean

  • Scalar - String, Integer, Long, Float, Double, Byte, Short, Character, Boolean.

  • Array - An array of either the allowable primitive or scalar types.

  • Collection - An object implementing the Collection interface that contains scalar types.

See <entry> types for information how to create these types.

121.6.7 Service Object

The service manager must not request the Blueprint Container for the service object until it is actually needed because a bundle requests it. The service object is represented in the value. This is a Metadata object that can be used to construct an object value, see Object Values.

For example:

<service id="fooService" ref="fooImpl".../>

<service id="fooService" ... >
   <bean class="com.acme.fooImpl"/>
</service>

The scope of the beans is ignored for the manager that provides the service object. Its value will only be created once the first time it is needed for the service.

121.6.8 Scope

A service manager must always register a Service Factory as service object and then dispatch the service requests to the service object. A service manager must obtain a single component instance as service object. This component instance is shared between all bundles. That is, even if the service object comes from a prototype scoped manager, only one instance is ever created per service manager.

If this component instance implements Service Factory, then all incoming service requests are forwarded to this single component instance.

121.6.9 Ranking

When registering a service with the service registry, an optional service ranking can be specified that orders service references. The service ranking is registered as the SERVICE_RANKING property defined in the OSGi service layer. When a bundle looks up a service in the service registry, given two or more matching services, then the one with the highest number will be returned. The default ranking value for the OSGi service registry is zero, therefore, this property must not be registered when ranking is zero, which is also the default value.

For example:

<service ref="fooImpl" interface="com.acme.FooImpl"
            ranking="900" />

This will result in the following service property:

service.ranking=new Integer(900)

121.6.10 Registration Listener

The registrationListeners represent the objects that need to be called back after the service has been registered and just before it will be unregistered.

The listenerComponent must be a Target object; it is the target for the following callbacks:

  • registrationMethod - The name of the notification method that is called after this service has been registered.

  • unregistrationMethod - This method is called when this service will be unregistered.

The signatures for the callback methods depend on the scope and if the service object implements the ServiceFactory interface. The different possibilities are outlined in the following table.

Table 121.7 Interaction scopes and types for callback signature.

Scope Type Signature Comment
singleton ServiceFactory void(ServiceFactory,Map)

All service requests are handled by the component instance.

singleton T void( super T,Map)

T is assignable from the service object's type.

prototype ServiceFactory void(ServiceFactory,Map)

All service requests are handled by the first component instance.

prototype T void(,Map)

The first argument must be null because for prototype service objects, the component instance is created when a bundle requests the service. Therefore, at registration time there is no service object available.


If multiple signatures match, then all methods must be called in indeterminate order. At least one method must match.

The service manager must provide the registration listener with the current registration state when the listener is registered. This initial notification must take place before any other callback methods are called on this listener on other threads. That is, if the service is registered at that time, it must call the registration method and otherwise the unregistration method.

The following example shows two registration listeners, one with a referred bean and another one with an inlined bean.

<service ref="fooImpl" interface="com.acme.Foo">
   <registration-listener registration-method="reg"
            unregistration-method="unreg">
        <bean class="com.acme.FooListener"/>
    </registration-listener>
</service>

<service ref="fooImpl" interface="com.acme.Foo">
   <registration-listener registration-method="reg"
            unregistration-method="unreg" ref="fooListener"/>
</service>
<bean id="fooListener" class="com.acme.FooListener"/>

package com.acme;
public class FooListener {
  public void reg( Foo foo, Map properties ) { ... }
  public void unreg( Foo foo, Map properties ) { ... }
}

The manager that provides the registration listener object is an implicit dependency of the enclosing service manager. However, the registration listener component instance is specifically allowed to use to the service manager though this is technically a cyclic dependency. Therefore, a bean is allowed to be both be injected with a ServiceRegistration object from the service manager as well as being a registered listener to the same service manager.

In the following example, the foo service manager uses manager main, both as a registration listener as well as top-level bean main being injected with reference foo.

<service id="foo" interface="com.acme.Foo"ref="main">
  <registration-listener 
        registration-method="register" ref="main"/>
</service>

<bean id="main" class="com.acme.Main" init-method="done">
    <property name="foo" ref="foo"/>
</bean>

121.6.11 Enabled

A service manager needs a service object that is referred to by the value Metadata property. This value can in its turn depend on other managers transitively. If any of these managers are service reference managers, then they can be satisfied or not. If these service reference managers are marked to be mandatory, then they influence the enabled state of the first service manager. Only if all of these mandatory service reference managers in the dependency graph are satisfied, then the first service manager is enabled.

A service manager must have a Service Factory registered with the OSGi service registry after the primary initialization of the Blueprint Container has been done until the Blueprint Container is destroyed while it is enabled. See see Service Registration.

121.6.12 Activation and Deactivation

When a service manager is activated, it must actuate its registration listeners. Each registration listener must be called back during its actuation with the current service registration state as described in the Registration Listener. Normally, this will also request the container for a service object but this can be further delayed in certain circumstances. See Service Object for more details.

During deactivation, a service manager must disable any registration listeners and release any dependencies it has on these component instances.

121.7 Service Reference Managers

The reference, and reference-list elements are all service references. They select a number of services in the service registry. The structure of these elements is as follows:

reference       ::= <reference-listener>* 
reference-list  ::= <reference-listener>*

The inheritance hierarchy for service references is depicted in Figure 121.9 on page .

Figure 121.9 Inheritance hierarchy for service references

Inheritance hierarchy for service references

121.7.1 Service Reference

The service reference managers have almost identical Metadata and share most behavior. The only schema differences between a reference manager and a reference-list manager are:

  • timeout - A reference manager supports a timeout.

  • memberType - The reference-list can define its member-type

The features of the service references are explained in the following table.

Table 121.8 Service Reference Manager Features

Attribute or Element Type ServiceReference-Metadata Description
id ID

id

: String

The component id of a top level manager

activation

  lazy

| eager

activation

: int

Defines if this service reference is lazily of eagerly initialized. If not explicitly set, the blueprint element's value for the default-activation attributes is used. If this is also not set, the value is eager. See also Lazy and Eager.

depends-on NCName*

dependsOn

: List<String>

Explicit list of component ids that are the dependencies. These managers must be activated before this service reference's activation. See Explicit Dependencies. This is a whitespace separated List.

availability

  mandatory

| optional

availability

: int

Defines if a service reference is mandatory or optional. The default for the availability attribute is defined by the default-availability attribute in the blueprint element. If the default-availability attribute is not defined, the value is mandatory.

interface qname

interface

: String

A single name of an interface class. It is allowed to not specify an interface name.

component-name NCName

componentName

: String

Points to another manager in another Blueprint Container registered in the service registry. If set, the component name must be part of the effective filter.

filter filter

filter

: String

The given filter string, can be null.

<reference-listener> See <reference-listener>.

referenceListeners

: List<Listener>

The Metadata of the reference listeners


The additional constraints for service references are:

  • The interface, if set, must refer to a public interface.

121.7.2 <reference>

A reference manager, selecting a single service, has the additional feature explained in the following table.

Table 121.9 Reference Features

Attribute or Element Type Reference Metadata Description
timeout long >= 0

timeout

: long

The timeout in ms. Zero is indefinite.


An additional constraint on the reference is:

  • The timeout must be equal or larger than zero.

121.7.3 <reference-list>

A reference-list manager, selecting multiple services, has the additional feature explained in the following table.

Table 121.10 Reference-list Features

Attribute or Element Type Reference List Metadata Description
member-type

  service-

  object

| service-

  reference

memberType

: int

Defines if the members of the list are ServiceReference objects or the proxies to the actual service objects.


121.7.4 <reference-listener>

The reference element can notify reference listeners of the service selection changes with the referenceListeners. The reference-listener element has the following structure:

reference-listener  ::= target*

The reference-listener element defines the callback methods for binding and unbinding a service.

Table 121.11 Reference Listener Features

Attribute or Element Type Reference Listener Description
ref NCName

listenerComponent

: Target

A reference to a top level target manager.

bind-method method

bindMethod

: String

The name of the method to call after the service has been bound. See Reference Listeners.

unbind-method method

unbindMethod

: String

The name of the method to call before the service will be unbound. See Reference Listeners.

<...> target

listenerComponent

: Target

An inlined target manager


The additional constraints are:

  • The ref attribute and the inlined manager are mutually exclusive.

  • Either or both bindMethod and unbindMethod must be specified.

  • At least one specified method must exist with each given method name, see Reference Listeners.

121.7.5 Provided Object For a Reference

The provided object for a service reference manager is a proxy backed by a service object from the service registry. Therefore, even though the injected object will remain constant, it can change its reference to a backing service at any time, implying it can only be used with stateful services if reference listeners are used. If use when no suitable backing service is available, it will wait until it times out. See Service Dynamics for more details. The model is depicted in Figure 121.10.

Figure 121.10 Constant references with dynamic selection

Constant references with dynamic selection

The following example shows how a property can be set to the service object.

public class C {
    public void setProxy(T ref) { ... }
}
<reference id="p" interface="T"/>
<bean id="c" class="C">
    <property name="proxy" ref="p"/>
</bean>

121.7.6 Provided Object For a Reference-list

The reference-list provided object implements the List interface; this List contains proxies to the backing services. These proxies do not have a timeout. That is, when a proxy from a reference-list is used, it must not wait when the backing service is no longer available but it must immediately throw a Service Unavailable Exception.

Changes to the list are dynamic. When a backing service is unregistered, the corresponding proxy is removed from the list synchronously with the service event. When a new service enters the selection, it is added synchronously with the service event. Proxies to newly discovered services must be added at the end of the list. The structure is depicted in Figure 121.11.

Figure 121.11 Constant reference to list with dynamic selection

Constant reference to list with dynamic selection

The member type of the list depends on the memberType. If this is set to:

  • service-object - Inject a List of service objects, this is the default.

  • service-reference - Inject a list of ServiceReference objects

If generics information is available, then it is an error if the generic member type of the target list is not assignable with the memberType. If the member target type is in itself specified with generic arguments, like List<T<U>>, then the assignment must fail because this would require conversion and no conversion can take place for this assignment. For information about generics, see Generics.

121.7.7 Read Only Lists

The list is a read-only view on the actual set of proxies to the service objects. This List object must only support the following methods:

contains(Object)
containsAll(Collection)
equals(Object)
get(int)
hashCode()
indexOf(Object)
isEmpty()
iterator()          // no remove method
lastIndexOf(Object)
listIterator()      // not supported
listIterator(int)   // not supported
size()
subList(int, int)   // same list type as parent
toArray()
toArray(T[])

All other methods must throw an Unsupported Operation Exception. The List Iterator is not supported for these lists.

121.7.8 Selection

A service reference must provide a selection of services from the service registry. The Blueprint Container must logically use a filter for the selection that is the and (&) of the following assertions:

  • The interface, if specified

  • If componentName is not null, a filter that asserts osgi.blueprint.compname=$componentName This is a convenience function to easily refer to managers in other Blueprint Containers. Registered Blueprint services will automatically get this property set to their blueprint name.

  • If filter is not null, the filter

The selection is defined as the set of Service References selected by the given filter.

121.7.9 Availability

A service reference is satisfied when one or more services match the selection. The availability is used to specify whether a service reference needs to be satisfied before initialization, see Grace Period, or if it controls the registration state of any service managers that depend on this service reference manager (explicit and implicit), see Mandatory Dependencies. The availability can have the following values:

  • mandatory - Mandatory indicates that the service reference needs to be satisfied.

  • optional - Optional indicates that the satisfaction of this reference is not relevant for any registered services, or for the grace period.

It is an error to declare a mandatory reference to a service that is registered by the same bundle. Such a definition could cause either deadlock or a timeout.

The fact that Blueprint specification has mandatory service references gives no guarantee that a valid service object is available when the service reference is used, in the dynamic world of OSGi, services can get unregistered at any time.

The following example declares a mandatory service reference for a single service. The usage of the reference can stall a maximum of 5 seconds if no service matches the selection.

<reference 
    id          ="log" 
    interface   ="org.osgi.service.log.LogService"
    availability="mandatory"
    timeout     ="5000" />

121.7.10 Reference Listeners

The referenceListeners are represented as ReferenceListener objects. They define the following callbacks:

  • bindMethod - Called after a service is selected by the service reference manager. For a reference manager, this method can be called repeatedly without an intermediate unbind callback. This happens when a service is unregistered but a replacement can be found immediately.

  • unbindMethod - Called when the service is no longer used by the service reference manager but before it has been returned to the service registry with the unget method. For a reference manager, no unbind method is called when the service can immediately be replaced with an alternative service when the service goes away.

A reference listener callback can have any of the following signatures:

  • public void(ServiceReference) - Provide the ServiceReference object associated with this service reference. This callback type provides access to the service's properties without actually getting the service.

  • public void( super T) - Provide the proxy to the service object, where T is on of the types implemented by the service object proxy.

  • public void ( super T,Map) - Provide the proxy to the service object. T is a type that is assignable from the service object. The Map object provides the service properties of the corresponding ServiceReference object.

All signatures must be supported regardless of the value of memberType that was specified in the reference-list. The service object given to the reference listeners must be the proxy to the service object.

The callbacks must be made synchronously with the corresponding OSGi service event. For reference-list callbacks, the service proxy is guaranteed to be available in the collection before a bind callback is invoked, and to remain in the collection until after an unbind callback has completed.

If a service listener defines multiple overloaded methods for a callback, then every method with a matching signature is invoked in an undefined order.

For example, the following definition will result in calling all the setLog methods on a FooImpl object:

<reference id="log"
        interface="org.osgi.service.log.LogService">
  <reference-listener
        bind-method="setLog">
        <bean class="com.acme.FooImpl"/>
    </reference-listener>
</reference>

public class FooImpl {
    public void setLog(Object o, Map m) { ... }
    public void setLog(LogService l, Map m) { ... }
    public void setLog(ServiceReference ref) { ... }
}

The manager that provides the reference listener object is treated as an implicit dependency of the enclosing service reference. This manager is specifically allowed to use to the service reference in a property injection or constructor argument, though this is technically a cyclic dependency. Therefore, a bean must be allowed to both be injected with a reference as well as listening to the bind and unbind callbacks of that same reference.

In the following example, the foo reference manager uses manager main, both as a reference listener as well as manager main being injected with reference foo.

<reference id="foo" interface="com.acme.Foo">
  <reference-listener bind-method="setL" ref="main"/>
</reference>
<bean id="main" class="com.acme.Main">
    <property name="r" ref="foo"/>
</bean>

121.7.11 Service Proxies

The Blueprint extender must generate proxies for the service reference managers. Reference managers provide proxies that dynamically select a backing service, which can change over time. A reference-list provides a list of proxies that have a fixed backing service, these proxies are added and removed from the list. Based on the selection, they do not have a time-out.

The backing service for a reference proxy must not be gotten from the OSGi service registry until an actual service object is needed, that is, when an actual method is called on the proxy. If the backing service becomes unregistered, then the proxy must unget the reference to the backing service (if it had gotten it) and get another service object the next time a method on the proxy is called. If a replacement can be found immediately, the reference listener's bind method must be called without calling the unbind method. Other threads that need the same service object must block until the service object has become available or times out.

The proxies must implement all the methods that are defined in the interface. The interface must refer to an interface, not a class. The proxy must only support the methods in the given interface. That is, it must not proxy methods available on the service object that are not available in the given interface. If no interface is defined, the proxy must be implemented as if the interface had no methods defined.

Blueprint bundles must ensure that the proper semantics are maintained for hashCode and equals methods. If these methods are not defined in the interface, then the proxy must use the default semantics of the Object class for equals and hashCode methods.

121.7.12 Activation and Deactivation

Service reference managers are active before activation because they must handle the enable status of service managers.

During activation, a service reference must actuate its listeners and provide these listeners with the initial state of the reference. For a reference, if there is a selected object, the bind method must be called with the proxy object, otherwise the unbind method must be called with a null as proxy object. For a reference-list, the bind method must be called for each member of the list. If the list is empty, the unbind method must be called with a null as proxy object.

During deactivation, the listeners must be disabled.

121.8 Object Values

Top-level managers can use object values in different places. These object values are defined with XML elements and attributes. After parsing, they are all converted to sub-interfaces of the Metadata interface, transitively reachable from top-level managers. For example, the following definition creates a bean that is injected with the byte array: byte[] {7,42}:

<bean class="com.acme.FooImpl">
    <property name="array">
        <array value-type="byte">
            <value>7</value>
            <value>42</value>
        </array>
    </property>
</bean>

This definition provides the configuration data for an array value, which is represented by the CollectionMetadata interface. A Metadata object can be used to construct its object value during runtime whenever a new object must be constructed.

In most places where an object value can be used, it can be anything, including objects provided by a managers and even null. However, maps require non-null keys. The object values are therefore split in value and nonNullValue types.

The syntax for object values has the following structure:

nonNullValue ::= <ref>
               | <idref>
               | <value>
               | <map>
               | <props>
               | collection
               | manager // see manager
value        ::= nonNullValue | <null>
collection   ::= <list> | <set> | <array>

Object values also include inlined managers. The use of an inlined manager for an object value means that manager will provide a value every time the object value is constructed. Each of the object values is created anew and the types are mutable, except for the service references. The use of managers in object values must create an implicit dependency between the top level managers and any transitively reachable manager from their Metadata.

121.8.1 <ref>

The ref element is a reference to a top-level manager in the same Blueprint Container. The ref element has a single attribute component-id.

Table 121.12 Ref Features

Attribute Type Ref Metadata Description
component-id NCName

componentId

: String

A reference to a top level manager.


For example, the following definition uses the foo manager to instantiate the service object.

<service id="fooService" interface="com.acme.Foo">
    <ref component-id="fooImpl"/> 
</service>
<bean id="fooImpl" class="com.acme.FooImpl"/>

public class FooImpl implements Foo { }

121.8.2 <idref>

The idref element provides the component id of another manager in the same Blueprint Container. This reference can then be used by the application to look up a manager in the Blueprint Container during runtime. The idref element is a safe way to provide a component id because the Blueprint Container will verify that the component id exists, thereby showing errors early. The idref does not create an implicit dependency on the given manager.

Table 121.13 IdRef Features

Attribute Type Id Ref Metadata Description
component-id NCName

componentId

: String

A reference to a top level manager.


The following example provides the foo object with the reference to the database.

<bean id="foo" class="com.acme.FooImpl">
    <property name="db">
        <idref component-id="jdbc"/>
    </property>
</bean>

<bean id="jdbc" ... />

The following definition is equivalent to except that a non existent component id will not be detected until the foo object access the Blueprint Container. In the previous example this was detected directly after the definitions were parsed.

<bean id="foo" class="com.acme.FooImpl">
    <property name="db" value="jdbc"/>
</bean> 
<bean id="jdbc" ... /> 

121.8.3 <value>

A value element represents an object that can directly be constructed from a string formed by its text contents.

Table 121.14 Value Features

Attribute, Element Type Value Metadata Description
type type

type

: String

The optional type name to be used in type converting the given string to a target type. This type can commit the conversion to a specific choice. If this type is not set, then it must return null. For the type syntax, see Syntax for Java types.

... <<type>>

stringValue

: String

The string value that must be converted to the target type, if set.


If a value element is used as a member in a list, map, array, or set then the enclosing collection can define a default value for the type attribute of its value elements.

The following example creates a list of two OSGi version objects.

<list value-type="org.osgi.framework.Version">
    <value>1.3.4</value>
    <value>5.6.2.v200911121020</value>
</list>

The corresponding Java code is:

Arrays.asList( new Version("1.3.4"), 
    new Version("5.6.2.v200911121020") )

121.8.4 <null>

A null element results in a Java null. It has no attributes and no elements. It corresponds to Null Metadata.

121.8.5 <list>, <set>, <array>

Lists, sets, and arrays are referred to as collections. List and array are ordered sequences of objects, where equal objects can occur multiple times. A set discards equal objects.

The structure of a collection element is:

collection  ::=  value *
 

Table 121.15 Collection Features

Attribute or Element Type Collection Metadata Description
value-type type

valueType

: String

Optionally set the type for ValueMetadata children.

collectionClass

: Class<

  List | Set | Object[] >

The actual collection class to be used, derived from the appropriate definition.

<...> object*

values

: List<Metadata>

The Metadata for the children of the collection


The valueType sets the default for any contained ValueMetadata objects. The result of a collection element is an object that implements the given collection interface or is an Object[]. That is, the resulting object is mutable and can be used by the application. However, type conversion can create a copy of this list.

The following example creates a List of Lists of 2x2 of int values:

<list>
    <list value-type="int">
        <value>2</value>
        <value>7</value>
    </list>
    <list value-type="int">
        <value>9</value>
        <value>5</value>
    </list>
</list>

The corresponding Java code is:

Arrays.asList( 
    new int[] {2,7},
    new int[]{9,5},
)

121.8.6 <map>

A map is a sequence of associations between a key and some object., this association is called an entry. The structure of a map element is therefore:

map ::= <entry> *

Table 121.16 Map Features

Attribute or Element Type Map Metadata Description
key-type type

keyType

: String

Optional default type for keys. For the syntax see Syntax for Java types.

value-type type

valueType

: String

Optional default type for values. For the syntax see Syntax for Java types.

<entry> See <entry>.

values

: List<MapEntry>

The MapEntry object for the children of the map or properties.


There are no additional constraints.

121.8.7 <entry>

The entry element provides an association between a key and a value. The structure of the element is:

entry   ::= <key> object
key     ::= nonNullValue

Table 121.17 Entry Features

Attribute Type Map Entry Description
key <<type>>

key

: NonNullMetadata

Specify the key of the entry.

key-ref NCName

key

: NonNullMetadata

Reference to a top-level manager

<key> nonNull-Value

key

: NonNullMetadata

Contains an inlined value that is never null.

value <<type>>

value

: Metadata

Specify the value directly, this will be a string type.

value-ref NCName

value

: RefMetadata

A reference to a top-level manager

<...> object

value

: Metadata

An inlined manager


Additional constraints:

  • key, key-ref attributes and key element are mutually exclusive.

  • value, value-ref attributes and value element are mutually exclusive.

  • The resulting object of a key must not be a primitive type.

The following example shows the different way an entry can get its key. In this case the value is always a string.

<map>
    <entry key="bar"     value="..."/>    // 1
    <entry key-ref="bar" value="..."/>    // 2
    <entry value="...">                   // 3
        <key>
            <value type="org.osgi.framework.Version">
                2.71
            </value>
        </key>
    </entry>
</map>

The previous example is equivalent to the following Java code:

Map m = new HashMap();
m.put( "bar", "...");
m.put( container.getComponentInstance("bar"), "...");
m.put( new Version("2.71"), "...");

The following examples shows the different ways a value of an entry can be defined.

<map>
    <entry key="1" value="1"/>
    <entry key="2" value-ref="foo"/>
    <entry key="3">
        <value type="org.osgi.framework.Version">3.14</value>
    </entry>
</map>

The previous code is equivalent to the following Java code.

Map m = new HashMap()
m.put("1", "1");
m.put("2", container.getComponentInstance("foo"))
m.put("3", new Version("3.14"));

121.8.8 <props>

The props element specifies a Properties object. The structure of a props element is as follows:

 props  ::= prop *

Each prop element is an association between two strings. It defines the following attributes:

  • key - A string specifying the property key. This attribute is required.

  • value - A string specifying the property value.

The following example initializes the same Properties object in two s ways.

<props>
    <prop key="1">one</prop>
    <prop key="2">two</prop>
</props>

<props>
    <prop key="1" value="one"/>
    <prop key="2" value="two"/>
</props>

This is equivalent to the following Java code:

Properties p = new Properties();
p.setProperty( "1", "one");
p.setProperty( "2", "two");

121.8.9 Manager as Value

Each manager can be the provider of component instances that act as object values. When a manager is used in an object value, then that is the manager asked to provide a component instance. The managers are specified in manager. The simple example is a bean. Any inlined bean can act as an object value. For example:

<list>
    <bean class="com.acme.FooImpl"/>
</list>

Some managers have side effects when they are instantiated. For example, a service manager will result in a ServiceRegistration object but it will also register a service.

<map>
    <entry key="foo">
        <service interface="com.acme.Foo">
            <bean class="com.acme.FooImpl"/>
        </service>
    </entry>
</map>    

121.9 Dependency Injection

A bean has a recipe for constructing a component instance with a constructor or factory and then providing it with its properties. These properties are then injected with object values, see Object Values.

The following types of dependencies can be injected:

  • Constructor arguments - The arguments specify the parameters for a constructor.

  • Static Factory arguments - The arguments specify the parameters for a static method.

  • Instance Factory arguments - The arguments specify the parameters for a method on an object provided by another manager.

  • Properties - The value of the Bean Property specifies the single parameter for the property's set method.

In all the previous cases, the Blueprint Container must find an appropriate method or constructor to inject the dependent objects into the bean. The process of selecting the correct method or constructor is described in the following section, which assumes a Bean Argument as context, where a Bean Property acts as a Bean Argument without an index or type set.

121.9.1 Signature Disambiguation

Constructors, factory methods, and property set methods are described with Metadata. The Blueprint Container must map these descriptions to an actual method or constructor. In practice, there can be multiple methods/constructors that could potentially map to the same description. It is therefore necessary to disambiguate this selection. Both factory methods and constructors have the same concept of signatures. A signature consists of an ordered sequence of zero or more types. For methods, only publicly accessible methods with the appropriate name are considered. For constructors, all publicly accessible constructors are considered. The disambiguation process described here is valid for all constructors and methods because the signature concept applies to both of them.

  1. Discard any signatures that have the wrong cardinality

  2. Find the list of signatures that have assignable types for each argument in their corresponding positions. Assignable is defined in Type Compatibility. If a type was specified for an argument, then this type must match the name of the corresponding reified type in the signature exactly.

  3. If this result list has one element, then this element is the answer. If this list has more than one element, then the disambiguation fails.

  4. Otherwise, find the list of signatures that have compatible types for each argument in their corresponding positions. Compatibility is defined in Type Compatibility.

  5. If this result list has one element, then this element is the answer. If the list has more than one element, then the disambiguation fails.

  6. If the arguments cannot be reordered (the index of the argument is used and is thus not -1, or there are less than two arguments) then the disambiguation fails.

  7. Find all signatures that match a re-ordered combination of the arguments. Reordering must begin with the first argument and match this argument against the first assignable types in a signature, going from position 0 to n. If the type is assignable from the argument, then it is locked in that position. If the argument has a type, then it must exactly match the name of the selected signature type. The same is done for the subsequent arguments. If all arguments can find an exclusive position in the signature this way, than the signature is added to the result.

  8. If the result list contains one signature, then this is the resulting signature. If the list has more than one element, then the disambiguation fails.

  9. Repeat step 6, but now look for compatible types instead of assignable types.

  10. If the result list contains one signature, then this is the resulting signature.

  11. Otherwise, the disambiguation fails

An example elucidates how the disambiguation works. Assuming the following definition and classes:

<bean ...>
    <argument>
        <bean class="Bar"/>
    </argument>
    <argument>
        <bean class="Foo"/>
    </argument>
<bean>

public class Bar extends Foo {}
public class Foo {}

The following bullets provide examples how signatures are matched against the previous definition.

  • (Bar,Foo) - The arguments will be in the given order and the ordered match will succeed. This is the normal case.

  • (Foo,Bar) - This will not match because in the re-ordered match, the Bar argument (which is a Foo sub-type) is matched against the first argument. The second Foo argument can then no longer find a compatible type because that slot is taken by the Bar instance.

  • (Object,Object) - This will be called with (aBar,aFoo).

Multiple constructors on a class can require disambiguation with the arguments type. In the following example, the Multiple class has two constructors that would both match the constructor arguments because a String object can be converted to both a File object and a URL object.

public class Multiple {
    public Multiple(URL a);
    public Multiple(File a);
}

An attempt to configure a Multiple object without the type will fail, because it is not possible to determine the correct constructor. Therefore, the type should be set to disambiguate this:

<bean class="Multiple">
  <argument type="java.net.URL" value="http://www.acme.us"/>
</bean>

121.9.2 Type Compatibility

During injection, it is necessary to decide about type assignability or type compatibility in several places. If generics are present, a type must be reified in its class, see Generics. In this specification, the canonical representation for a type is T<P1..Pn>, where n is zero for a non-parameterized type, which is always true in a VM less than Java 5. The ReifiedType class models this kind of type.

If type T or S is primitive, then they are treated as their corresponding wrapper class for deciding assignability and compatibility. Therefore, a type T<P1..Pn> (target) is assignable from an object s of type S (source) when the following is true:

  • n == 0, and

  • T.isAssignableFrom(S)

T<P1..Pn> is compatible with an object s of type S when it is assignable or it can be converted using the Blueprint built-in type converter. The convertability must be verified with the canConvert(s,T<P1..Pn>) method. That is, type compatibility is defined as:

  • assignable(T<P1..Pn>,S), and

  • cs.canConvert(s,T<P1..Pn>) returns true

Where cs is the Blueprint built in type converter that also uses the custom type converters.

121.9.3 Type Conversion

Strings in Blueprint definitions, object values, and component instances must be made compatible with the type expected by an injection target (method or constructor argument, or property) before being injected, which can require type conversion. The Blueprint Container supports a number of built-in type conversions, and provides an extension mechanism for configuring additional type converters. Custom type converters have priority over built-in converters.

The goal of the type conversion is to convert a source object s with type S to a target type T<P1..Pn>. The conversion of the Blueprint built-in type converter must take place in the following order:

  1. If T<P1..Pn> is assignable from S, which implies n=0, then no conversion is necessary, except that primitives must be converted to their wrapper types.

  2. Try all type converters in declaration order with the canConvert(s,T<P1..Pn>) method, exceptions are ignored and logged. The first converter that returns true is considered the converter, its result is obtained by calling convert(s,T<P1..Pn>). Exceptions in this method must be treated as an error.

  3. If T is an array, then S must be an array or it must implement Collection, otherwise the conversion fails. Each member of array s must be type converted to the component type of T using the generics information if available, see the getComponentType method on Class. This is a recursive process. The result must be stored in an array of type T.

  4. If T implements Collection, then S must be an array or implement Collection, otherwise the conversion fails. If the platform supports generics, the members of object s must be converted to the member type of the collection if this is available from the generics information, or to Object otherwise. The Blueprint Container must create a target collection and add all members of s to this new object in the iteration order of s. The target collection depends on type T:

    • If T is one of the interfaces listed in Concrete Types for Interfaces, then the target collection must be the corresponding concrete class.

    • T must represent a public concrete class with an empty publicly accessible constructor, the target collection is then a new instance of T.

    • Otherwise T represents an interface and the conversion must fail.

  5. If T implements Map or extends Dictionary, then S must implement Map or extend Dictionary as well, otherwise the conversion fails. If the platform supports generics, the members of map s must be converted to the key and value type of the target map. This is a recursive process. Without generics, the members are not converted and put as is.

    The target map depends on T:

    • If T is a public concrete class (not interface) with an empty publicly accessible constructor then the target map must be a new instance of T.

    • If T is one of the Map interfaces or Dictionary listed in Concrete Types for Interfaces, then the target map must be the corresponding concrete class.

    • Otherwise, the conversion fails.

  6. If T is one of the primitive types (byte, char, short, int, long, float, double, boolean) then treat T as the corresponding wrapper class.

  7. If T extends class Number and S extends also class Number then convert the source to a number of type T. If the target type cannot hold the value then the conversion fails. However, precision may be lost if a double or float is converted to one of the integer types.

  8. If source type S is not class String, then the conversion fails.

  9. The conversion is attempted based on the target type T from the string s. The following target types are supported:

    • boolean or Boolean - Construct the appropriate boolean type while accepting the following additional values for true and false respectively:

      • yes, no

      • on, off

    • Character - The string s must have a length of 1, this single character is then converted to a Character object.

    • Locale - The string s is converted to a Locale using the following syntax (no spaces are allowed between terms).

      locale  ::= <java language-code> ( '_' country)+
      country ::= <java country-code> ('_' <java variant-code>)+
    • Pattern - Create the Pattern object with Pattern.compile(String).

    • Properties - Create a new Properties object and load the properties from the string. The string must follow the format described with the Properties.load method.

    • Enum subclass - Convert the string s to the appropriate member of the given enum with the Enum.valueOf method. If the string is not one of the enum values, then the conversion must fail.

    • Class - The string s must conform to the syntax in Syntax for Java types. This type must be loaded through the Bundle's loadClass method. The resulting class must match any generic constraints on T. If this fails, the conversion fails.

  10. If target type T has a constructor (String), then use this constructor to create an instance with the source string s. This convention caters for many of the built-in Java types such as BigDecimal, BigInteger, File, URL, and so on, as well as for custom types.

If none of the above steps has found a proper conversion than the conversion fails. Failing a conversion must end with throwing an Illegal Argument Exception.

121.9.4 Type Converters

A type converter converts a source type to a target type. The source type for a type converter is not constrained. A type converter must support the following methods:

  • canConvert(Object,ReifiedType) - A light weight method that inspects the object and returns true if it can convert it to the given Reified Type, false otherwise. Converters normally can convert a type S to a type T<...>. However, converters can convert to multiple types and the value of the source object can influence the returned type. For example, a converter could convert a string to a type based on its content.

  • convert(Object,ReifiedType) - The actual conversion method. This method should not fail if the canConvert method has returned true.

The ReifiedType class provides access to the target class. In a Java 1.4 environment, the ReifiedType object will provide a Class object for conversion and no type arguments. In a Java 5 environment, the ReifiedType object provides access to the reified class as well as the type arguments. Generics and reified types are described in Generics.

Type converters are normal managers with some limitations due to the dependency handling. If they depend on general managers or services then there is a change that cyclic dependencies are created.

Converters must be defined in the type-converters element, see <type-converters>, to be registered as a converter. Component instances of managers in this section must implement the Converter interface. Converters must also only transitively depend on built-in converters. It must be possible to initialize all converters before any of them are used. Type converters should not use the type conversion before all type converters are fully configured.

Converters are ordered within one definition resource but there is no resource ordering, so the overall ordering is not defined, making it a good practice to concentrate all converters in a single XML definition. The definition ordering is used during type conversion. That is, converters are not ordered by their specialization, a converter that is earlier can convert a more general type will override a converter that is later in the list but could have converted to a more specific type.

Converters must always use the type arguments of the given Reified Type, even if they are running on Java 1.4. The default behavior of the Reified Type will automatically work.

The following example demonstrates how a converter can use generics to use an AtomicReference<T> whenever type T is supported. Such a type could be for a property like:

public void setInteger( AtomicReference<Integer>atomic );

The Atomic Converter uses the generic argument to convert a source object to an Integer and then creates an AtomicReference with this converted object. The definition of the type converter looks like:

<type-converters>
  <bean class="AtomicConverter">
    <argument ref="blueprintConverter"/>
  </bean>
</type-converters> 

The Blueprint converter is injected in the constructor of the AtomicInteger class, in order to allow the conversion of the generic arguments. The Blueprint built-in type converter must not be used before all type converters are registered because a needed type converter might not have been registered yet. This is the reason type converters should not require type conversion in their initialization because the state of this converter is not well defined at this time.

The conversion class looks like:

public class AtomicConverter {
  Converter bpc;
  public AtomicConverter(Converter bpc) { this.bpc=bpc; }

  public boolean canConvert(Object s,ReifiedType T) {
    return T.getRawClass() == AtomicReference.class
    && bpc.canConvert(s, T.getActualTypeArgument(0));
  }

  public Object convert( Object s, ReifiedType T )
      throws Exception {
    Object obj = bpc.convert(
        s,T.getActualTypeArgument(0) );

     return new AtomicReference<Object>(obj);
  }
}

Any injection that now targets an AtomicReference<T> value will automatically be converted into an AtomicReference of the appropriate type because of the example converter. The following definitions test this behavior:

public class Foo<T extends Integer> {
  public Foo( AtomicReference<T> v) {}
}

<bean id="foo" class="Foo"> <argument value="6"/> </bean> 

This definition will create an foo object with the Foo(AtomicReference<T>) constructor. The source type is a string and there is no assignability for an Atomic Reference, so the registered type converters are consulted. The Atomic Converter recognizes that the target T is an AtomicReference class and indicates it can convert. The convert method then uses the generic argument information, which is an Integer object in the example, to convert the string "6" to an Integer object and return the appropriate AtomicReference object.

121.9.5 Built-in Converter

A Blueprint Container must contain an environment manager called blueprintConverter. The related component instance must implement the Converter interface.

The built-in Converter provides access to the provided type converters as well as the built in types. This service provides the type conversion as defined in Type Conversion.

Injecting a reference to the blueprintConverter environment manager into a bean provides access to all the type conversions that the Blueprint Container and registered type converters are able to perform. However, if this converter is injected in a type converter, then by definition, not all custom type converters are yet registered with the built-in converter. Type converters should therefore in general not rely on type conversion during their construction.

121.9.6 Concrete Types for Interfaces

The Blueprint extender can choose an implementation class when it provides an instance during conversion to an interface as well as when it natively provides an object. The actual implementation class can make a noticeable difference in disambiguation, type conversion, and general behavior. Therefore this sections describe the concrete types an implementation must use for specific interfaces if the platform allows this.

Table 121.18 Implementation types for interfaces

Interface/Abstract class Implementation class

Collection

ArrayList

List

ArrayList

Java 5

Queue

LinkedList

Set

LinkedHashSet

SortedSet

TreeSet

Map

LinkedHashMap

SortedMap

TreeMap

Java 5

ConcurrentMap

ConcurrentHashMap

Dictionary

Hashtable


If possible, the instances of these types must preserve the definition ordering.

121.9.7 Generics

Java 5 introduced the concept of generics. Before Java 5, a type, was simply a class or interface, both represented by the Class object. Generics augment these classes and interfaces with additional type constraints. These type constraints are not available on an instance because an instance always references a raw Class. For an instance all generic type constraints are erased. That is, a List<Integer> object is indistinguishable from a List<String> object, which are indistinguishable from a List object. Objects always refer to a raw Class object, this is the one returned from the getClass method. This Class object is shared between all instances and can therefore not have the actual type constraints (like String, Integer in the list examples).

When a class is used the compiler captures the type constraints and associates them with the specific use and encodes them in a Type object. For example, a field declaration captures the full generic type information:

List<String> strings;

A field has a getGenericType method that provides access to a Type object, which is a super interface for all type information in the Java 5 and later runtime. In the previous example, this would be a Parameterized Type that has a raw class of List and a type argument that is the String class. These constraints are reflectively available for:

  • A superclass

  • Implemented interfaces

  • Fields

  • For each method or constructor:

    • Return type

    • Exception types

    • Parameter types

Generics influence the type conversion rules because most of the time the Blueprint extender knows the actual Type object for an injection. Therefore, conversion must take place to a type like T<P1..Pn>, where T is a raw Class object and P1..Pn form the available type parameters. For a non-parametrized class and for other VMs than 1.4, n is always zero, that is no type arguments are available. The P arguments are in itself instances of Type. The form T<P1..Pn> is called the reified form. It can be constructed by traversing the Type graph and calculating a class that matches the constraints. For example < extends List<T>> defines a wild card constraint, that has a List<T> as reified type, where T is a Type Variable defined elsewhere that can have additional constraints. The resulting type must be an instance of List<T>. A reified type will use an object implementing List for such an example because that is the only class that is guaranteed to be compatible. The rules to reify the different Type interfaces are:

  • Class - A Class represents unparameterized raw type and is reified into T<>. For example:

    String string;
  • ParameterizedType - A Parameterized Type defines a raw type and 1..n typed parameters. The raw type of the Parameterized Type is also reified and represents T. The arguments map directly to the arguments of the reified form. An example of a Parameterized Type is:

    Map<String,Object> map;
  • TypeVariable - Represents a Type Variable. A type variable is listed in a generics type declaration, for example in Map<K,V>, the K and V are the type variables. A type variable is bounded by a number of types because it is possible to declare a bounded type like: <A extends Readable&Closeable>. A Type Variable is reified by taking its first bound in reified form, this is the same as in Java 5 where the first bounds is the erasure type. However, this can fail if multiple bounds are present. An example of a Type Variable is:

    public <T extends ServiceTracker> void setMap(T st) {} 

    In this example, the parameter st will have a reified type of ServiceTracker.

  • WildcardType - A Wildcard Type constrains a type to a set of lower bounds and a set of upper bounds, at least in the reflective API. In the Java 5 and later syntax a Wildcard Type can only specify 0 or one lower and one upper bound, for example <T extends Number> constraints the Type Variable T to at least extend the Number class. A Wildcard Type is reified into its reified upper bound when no lower bound is set, and otherwise it is reified into its reified lower bound. An example of a Wildcard Type is seen in the example of a Type Variable.

  • GenericArrayType - A Generic Array Type represents an array. Its component type is reified and then converted to an array. The Reified Type will have the array class as reified class and the type arguments reflect the type arguments of the component type. For example:

    public void setLists(List<String>[] lists) {}

    This example will have a Reified Type of List[]<String>.

This specification is written to allow Java 1.4 implementations and clients, the API therefore has no generics. Therefore, the Type class in Java 5 and later cannot be used in the API. However, even if it could use the Type class, using the type classes to create the reified form is non-trivial and error prone. The API therefore provides a concrete class that gives convenient access to the reified form without requiring the usage of the Type class.

The ReifiedType class provides access to the reified form of Class, which is itself and has no type arguments. However, Blueprint extender implementations that recognize Java 5 generics should subclass the ReifiedType class and use this in the conversion process. The subclass can calculate the reified form of any Type subclasses.

121.10 Service Dynamics

The Blueprint Container specification handles the complexities of the dynamic nature of OSGi by hiding the dynamic behavior of the OSGi service registry, at least temporarily. This dynamic behavior is caused by service references that select one or more services that can come and go at runtime.

The Blueprint Container must handle the dynamics in the following way:

  • Proxied references - Service reference managers must provide a proxy implementing the specified interfaces, instead of the actual service object it refers to. The proxy must fetch the real service lazily. For reference managers, when a proxy is used, and no candidate is available, a candidate must be found within a limited time. If no candidate service is available during this time, a Service Unavailable Exception must be thrown. The reference-list manager also maintains proxies but these proxies must throw a Service Unavailable Exception immediately when the proxy is used and the backing service is no longer available.

    When proxied references are used with stateful services, then the application code must register a reference listener to perform the necessary initialization and cleanup when a new backing service is bound.

  • Conditional Service Registrations - The service manager is responsible for registering a service with the OSGi service registry. A service manager is statically dependent on the transitive set of managers that it depends on. If these static dependencies contain mandatory service references, then the manager's service must not be registered when any of these mandatory service references is unsatisfied, see Enabled.

121.10.1 Damping

When an operation is invoked on an unsatisfied proxy from a reference manager (either optional or mandatory), the invocation must block until either the reference becomes satisfied or a time-out expires (whichever comes first). During this wait, a WAITING event must be broadcast, see Events.

The default timeout for service invocations is 5 minutes. The optional timeout of the reference element specifies an alternate timeout (in milliseconds). If no matching service becomes available within the timeout, then a Service Unavailable Exception must be thrown. A timeout of zero means infinite and a negative timeout is an error.

For example:

<reference id="logService"
        interface="org.osgi.service.log.LogService" 
      timeout="100000" />

<bean id="bar" class="BarImpl">
  <property name="log" ref="logService"/>           
</bean>

When this Blueprint Container is instantiated, the reference manager provides a proxy for the Log Service, which gets injected in the log property. If no Log Service is available, then the proxy will have no backing service. If the bar object attempts to log, it will block and if the timeout expires the proxy must throw a Service Unavailable Exception.

If at some later point in time, a Log Service is registered then it becomes satisfied again. If bar now logs a message, the proxy will get the service object again and forward the method invocation to the actual Log Service implementation.

The damping ensures that a mandatory service reference that becomes unsatisfied does not cause the Blueprint Container to be destroyed. Temporary absences of mandatory services are tolerated to allow for administrative operations and continuous operation of as much of the system as possible.

A reference-list manager does not provide damping. It only removes the service proxy from the collection if its service goes away. Using a collection reference manager will never block, it will just have no members if its selection is empty. A timeout attribute is therefore not supported by the reference-list elements. However, the elements are proxied and it is possible that they throw a Service Unavailable Exception when used and the backing service has disappeared. The exceptions for a reference-list proxy will be thrown immediately when the proxy is used.

121.10.2 Iteration

The provided object of a reference-list manager implements the List interface. Depending on the memberType or the optional generics information, it provides a collection that contains the member objects, that is, either proxies to the service object, or ServiceReference objects. These collections are read-only for the receiver, however, their contents can dynamically change due to changes in the selection. The access to these collections with iterators must give a number of guarantees:

  • Safe - All iterators of reference-list managers must be safe to traverse according to the Iterator interface contract, even while the underlying collection is being modified locally or in another thread. If the hasNext method returns true, the iterator must return a member object on the subsequent next method invocation. If there is no longer a service object available when requested, then a dummy proxy must be returned that throws a Service Unavailable Exception whenever it is used.

  • Visibility - All the changes made to the collection that affect member objects not yet returned by the iterator must be visible in the iteration. Proxies for new services must be added at the end of the List. Proxies already returned can be affected by changes in the service registry after the iterator has returned them.

After the iterator has returned false for the hasNext method, no more objects can be obtained from it. A List Iterator must not be supported.

121.10.3 Mandatory Dependencies

A service manager can have mandatory service reference managers in its transitive dependencies. Such a service manager must ensure that the service object is registered with the OSGi service registry during the runtime phase when all its mandatory service references that it depends on are satisfied. This called tracking the dependency. A service manager is enabled when all its mandatory references in its dependencies are satisfied.

This tracking only works for dependencies declared directly in the definitions; dependencies established during runtime by calling the getComponentInstance method are not tracked.

In the following example, service manager S has a transitive dependency on the mandatory reference manager M, which means the Blueprint Container must ensure that the service object provided by bean A is registered when reference manager M is satisfied.

<service id="S" ref="A" interface="com.acme.Foo"/>
<bean id="A" class="com.acme.FooImpl">
   <property name="bar" ref="m"/>
</bean> 
<reference id="M" interface="com.acme.Bar"
     availability="mandatory"/>

However, if the dependency from manager A on manager M is not declared but created through code that manipulates the Blueprint Container then the dependency is not tracked.

121.11 Blueprint Container

The Blueprint Container has a registry where all top-level managers, as well as environment managers, are registered by their component id. The Blueprint Container can be injected in application code with the environment blueprintContainer manager. For example:

<bean class="com.acme.FooImpl">
    <property name="container" ref="blueprintContainer"/>
</bean>

The Blueprint Container allows application code to get objects that are provided by the top-level managers through the getComponentInstance method. However, the Blueprint Container should not be required to get a component instance; the proper way to use Blueprint is to inject them. This declarative approach makes the Blueprint Container aware of any dependencies; one of the primary goals of a dependency injection framework. The Blueprint Container's introspective features are commonly used for management and other non-application purposes.

The Blueprint Container is registered as a service during the runtime phase so that other bundles can use it for these, and other, purposes.

121.11.1 Environment Managers

The Blueprint Container provides a number of environment managers. These managers have defined names and provide convenient access to information about the environment. Environment managers cannot be overridden by explicitly defined managers because it is invalid to define a manager with an existing component id. All component ids starting with blueprint are reserved for this specification and future incarnations.

There is no XML definition for environment managers but their Metadata must be provided as ComponentMetadata objects.

The following ids are used for the environment managers:

  • blueprintContainer - The Blueprint Container.

  • blueprintBundle - A manager that provides the Blueprint bundle's Bundle object.

  • blueprintBundleContext - A manager that provides the Blueprint bundle's BundleContext object.

  • blueprintConverter - A manager that provides an object implementing the Converter interface. This represents the built-in conversion facility that the Blueprint Container uses to convert objects. See Built-in Converter.

121.11.2 Component Instances

The Blueprint Container provides access to the component instances that the top level managers can provide, as well as their Metadata. The Blueprint Container has the following methods for requesting a component instance and to find out what managers are available:

  • getComponentInstance(String) - This method will provide a component instance from the component id. If the manager has not been activated yet, it must atomically activate and ensure its explicit and implicit dependencies are activated transitively.

  • getComponentIds() - Returns a set of component ids in this Blueprint Container. These ids must consist of all top level managers (including calculated ids) and environment managers.

121.11.3 Access to Component Metadata

Each of the manager types has specific Component Metadata subtypes associated with it, except Environment managers that use Component Metadata. The Blueprint Container provides access by component id to the Component Metadata of the top level managers. However, managers can also be defined inline, in which case they do not have a component id. Therefore, the Blueprint Container can also enumerate all the managers that are represented by a Metadata sub-interface.

  • getComponentMetadata(String) - Answer the Component Metadata sub-type for the given component id. Environment managers will return a ComponentMetadata object, the other managers each have their own specific Metadata type.

  • getMetadata(Class) - Answer a collection with the Metadata of the given type, regardless if it is defined as/in a top-level or inlined manager. For example, getMetadata(ServiceMetadata.class) returns all Service Metadata in the Blueprint container. This includes all top level managers as well as any inlined managers. For Environment Managers, this method returns a ComponentMetadata object.

121.11.4 Concurrency

A Blueprint Container must be thread safe. Each method must handle the case when multiple threads access the underlying registry of managers. Activation of managers must be atomic. That is, other threads must be blocked until a manager is completely activated.

The Blueprint Container must handle reentrant calls.

121.12 Events

The Blueprint Container must track all Blueprint Listener services and keep these listeners updated of the progress or failure of all its managed bundles. The Blueprint Listener is kept informed by sending it events synchronously. These events are therefore normally delivered in order but in exceptional cases this can be seen out of order for a listener when new events are initiated synchronously from within a callback. Therefore, Blueprint Listener services should see the event as a notification, where actual work should be processed on another thread.

Blueprint Events must be sent to each registered Blueprint Listener service. This service has the following method:

  • blueprintEvent(BlueprintEvent) - Notify the listener of a new Blueprint Event. These events are send synchronously with their cause. That is, all listeners must be notified before the Blueprint Container continues to the next step.

The events must be delivered as BlueprintEvent objects. The event types that they represent, and the data that these objects carry, is further described in Blueprint Event.

A Blueprint Listener services must be given the initial state of all managed bundles before normal processing starts, see Replay.

Blueprint Listener services that throw Exceptions or do not return in a reasonable time as judged by the Blueprint extender implementation, should be logged, if possible, and further ignored.

121.12.1 Blueprint Event

The Blueprint Event supports the following event types:

  • CREATING - The Blueprint extender has started creating a Blueprint Container for the bundle.

  • GRACE_PERIOD - The Blueprint Container enters the grace period. This event can be repeated multiple times when the list of dependencies changes due to changes in the service registry.

  • CREATED - The Blueprint Container is ready. The application is now running.

  • WAITING - A service reference is blocking because of unsatisfied mandatory dependencies. This event can happen multiple times in a row.

  • DESTROYING - The Blueprint Container is being destroyed because the Blueprint bundle or Blueprint extender has stopped.

  • DESTROYED - The Blueprint Container is completely destroyed.

  • FAILURE - An error occurred during the creation of the Blueprint Container.

The Blueprint Event provides the following methods:

121.12.2 Replay

The Blueprint Extender must remember the last Blueprint Event for each ready bundle that it manages, see Initialization Steps. During the (synchronous) service registration event of a Blueprint Listener service, the Blueprint extender must inform the Blueprint Listener service about all its managed bundles by sending it the last known event for each bundle the Blueprint extender manages. This initial event is called the replay event, and is marked as such.

The replay event must be delivered to the Blueprint Listener service as the first event, before any other event is delivered, during the registration of the Blueprint Listener service. That is, the blueprintEvent method must have returned before the first non-replay event can be delivered and no events must be lost. The replay events must be sent every time a Blueprint Listener service is registered.

The set of managed bundles is defined by bundles that are active and are managed by the Blueprint extender, even if their initialization ended in failure.

The BlueprintEvent object for a replay event must return true for the isReplay() method in this situation, and false in all other situations.

121.12.3 Event Admin Mapping

When the Event Admin service is present, the Blueprint extender must create an Event Admin event for each defined Blueprint Event. This Event Admin event must be asynchronously given to the Event Admin service with the postEvent method.

The topic of the Event Admin event is derived from the Blueprint event type with a fixed prefix. All topics must have the prefix of:

TOPIC_BLUEPRINT_EVENTS

After this prefix, the name of the Blueprint Event type must be used as the suffix. That is, CREATING, GRACE_PERIOD, etc. For example, org/osgi/service/blueprint/container/GRACE_PERIOD.

For each Blueprint event the following properties must be included:

  • TYPE - The type of the Event, see Blueprint Event.

  • BUNDLE - (Bundle) The Bundle object of the Blueprint bundle

  • BUNDLE_ID - (Long) The id of the Blueprint bundle.

  • BUNDLE_SYMBOLICNAME - (String) The Bundle Symbolic Name of the Blueprint bundle.

  • BUNDLE_VERSION - (Version) The version of the Blueprint bundle.

  • EXTENDER_BUNDLE - (Bundle) the Bundle object of the Blueprint extender bundle.

  • EXTENDER_BUNDLE_ID - (Long) The id of the Blueprint extender bundle

  • EXTENDER_BUNDLE_SYMBOLICNAME - (String) The Bundle Symbolic Name of the Blueprint extender bundle.

  • EXTENDER_BUNDLE_VERSION - (Version) The version of the Blueprint extender bundle

  • TIMESTAMP - (Long) The time when the event occurred

  • CAUSE - (Throwable) The failure cause, only included for a FAILURE event.

  • DEPENDENCIES - (String[]) The filter of an unsatisfied service reference. Can only appear in a GRACE_PERIOD, WAITING or FAILURE event caused by a time-out.

  • EVENT - (BlueprintEvent) The BlueprintEvent object that caused this event.

The property names for Blueprint Listener events may be conveniently referenced using the constants defined in the org.osgi.service.event.EventConstants and EventConstants interfaces.

The Event Admin events do not follow the replay model in use for Blueprint Listener services. That is, the Event Admin must only be kept informed about events as they occur.

121.13 Class Loading

The module layer in OSGi provides advanced class loading rules that potentially can cause bundles to live in different class spaces. This means that not all bundles can collaborate because the classes involved in the collaboration can come from different class loaders, which results in confusing Class Cast Exceptions on classes with the same name. It is therefore crucial that the Blueprint Container uses the Bundle Context and the bundle class loader of the Blueprint bundle for all actions that are made on behalf of the Blueprint bundle. Especially, access to the OSGi service registry must use the Bundle Context of the Blueprint bundle. Any dynamic class loading must use the Blueprint bundle's loadClass method. The normal OSGi mechanics will then ensure class space consistency for resolved bundles.

121.13.1 Blueprint Extender and Bundle Compatibility

For many Blueprint bundles, there is no class space compatibility issue. These bundles do not use any Blueprint classes and are therefore by definition compatible with any extender. However, if the Blueprint bundle uses some of the Blueprint packages, it must import these packages. Blueprint Containers must verify that they are type compatible with the Blueprint bundle before they attempt to manage it. See Type Compatibility.

121.13.2 XML and Class Loading

The Blueprint definition resources contain textual references to classes. These textual references will be loaded with the class loader of the Blueprint bundle. This implies that all the classes of provided component instances must be either imported or available from the bundle.

The Blueprint specification has the following attributes and elements that can cause imports:

  • class

  • value-type

  • interface

  • interfaces

  • type

  • key-type

All these attributes and elements are defined with the Tclass and Ttype XML Schema type for the Blueprint namespace. The Tclass defines simple class names, and Ttype defines types defined in Syntax for Java types.

121.13.3 Foreign Bundle Context

When using the Blueprint Container in its Blueprint bundle, the types that the managers provide are guaranteed to be compatible with the caller.

When using a Blueprint Container service in another bundle (for example, getting it as a service) then there is no guarantee of type compatibility or even visibility between the versions of the types of the returned managers, and the versions of the types visible to the caller. Care must therefore be taken when casting the return value of the getComponentInstance method to a more specific type.

121.13.4 Converters and Class Loading

A converter is closely coupled to its target class. If the converter comes from another bundle, then the converter bundle must ensure class space consistency between the converter implementation and the target class. This can be achieved by specifying the target class in the uses directive.

For example:

Export-Package:  
     com.converters.ac;uses:="com.converters.dc"

A bundle that references a type converter defined in the Blueprint bundle does not need to export that type. When creating a Blueprint Container, the extender bundle uses the class loader of the Blueprint bundle.

121.13.5 Type Compatibility

Two bundles are type compatible for a given class if they both load the same class object, or if either bundle cannot load the given class.

To mitigate type incompatibility problems, a Blueprint extender must export the org.osgi.service.blueprint package. In the uses: directive, it should list any packages of classes that can be shared between the Blueprint extender and the Blueprint bundle. Blueprint bundles should import this package.

121.13.6 Visibility and Accessibility

The Blueprint Container must load any classes it needs through the Blueprint bundle's loadClass method. If a class can not be loaded, then the initialization fails. Class loading issues are further discussed in Class Loading.

The Blueprint Container must respect the accessibility of the class and any of its members. That is, the Blueprint Container must not use the setAccessibility method. All classes and reflected members must therefore be declared public or be implicitly public like the default constructor.

121.14 Metadata

An important aspect of the Blueprint specification is the so called metadata interfaces. These interfaces are used in the Blueprint Container to enable programmatic access to the XML definitions. During the parsing phase the Blueprint Container reads the XML and converts it to an object implementing the appropriate interface.

The XML elements and XML Schema types map to the Metadata interfaces. For example, <bean> maps to BeanMetadata. However, in several cases, the attributes and/or sub-elements in the Metadata interfaces are merged when possible. For example, the interface attribute and interfaces element in the service element are merged in the ServiceMetadata class' getInterfaces() method.

The interfaces are arranged in a comprehensive hierarchy that reflects their usage and constraints. This hierarchy is depicted in Figure 121.12 on page .

The hierarchy can roughly be divided in two parts. The first part is the sub-interfaces of the ComponentMetadata interface. These interfaces are defining the configuration data of the top-level and inlined managers. The manager's component instance(s) are injected with values during runtime. The configuration of how to create a specific value is also described with Metadata interfaces. For example, a Map object is described with configuration information in the MapMetadata interface. The hierarchy makes it clear that Component Metadata is also a value that can be injected. Keys in maps or properties can not be null. This is the reason the hierarchy is split at the top into a null value branch and a branch that can only generates non-null values.

The Target interface describes managers that can be used as the target for the reference listener or the registration listener, or a ref.

Figure 121.12 Metadata Interfaces Hierarchy

Metadata Interfaces Hierarchy

121.15 Blueprint XML Schema

The Blueprint schema included in this specification can be found in digital form at [9] OSGi XML Schemas.

<xsd:schema xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.osgi.org/xmlns/blueprint/v1.0.0"
    elementFormDefault="qualified" attributeFormDefault="unqualified"
    version="1.0.1">

    <xsd:annotation>
        <xsd:documentation>
            <![CDATA[
                This is the XML Schema for the OSGi Blueprint service 1.0.0
                development descriptor.  Blueprint configuration files
                using this schema must indicate the schema using the
                blueprint/v1.0.0 namespace.  For example,

                <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

                if used as a qualified namespace, "bp" is the recommended
                namespace prefix.
            ]]>
        </xsd:documentation>
    </xsd:annotation>

    <!-- Schema elements for core component declarations -->

    <xsd:complexType name="Tcomponent" abstract="true">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                    The Tcomponent type is the base type for top-level
                    Blueprint components.  The <bean> <reference>, <service>,
                    and <reference-list> elements are all derived from
                    the Tcomponent type.  This type defines an id attribute
                    that is used create references between different components.
                    Component elements can also be inlined within other component
                    definitions.  The id attribute is not valid when inlined.
                ]]>
            </xsd:documentation>
        </xsd:annotation>

        <xsd:attribute name="id" type="xsd:ID" />

        <xsd:attribute name="activation" type="Tactivation">
            <xsd:annotation>
                <xsd:documentation>
                    <![CDATA[
                    The activation attribute for this component.  This can either
                    be "eager" or "lazy".  If not specified, it
                    defaults to default-activation attribute of the enclosing
                    <blueprint> element.
                    ]]>
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>

        <xsd:attribute name="depends-on" type="TdependsOn">
            <xsd:annotation>
                <xsd:documentation>
                    <![CDATA[
                    depends-on identifies (by id) other components that this component
                    depends on.  The component only be activated after the
                    depends-on components are successfully activated.  Also, if there
                    are <reference> or <reference-list> elements with unstatisfied
                    manadatory references, then the depends-on relationship will also
                    be used to determine whether this service is enabled or not.
                    ]]>
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:element name="blueprint" type="Tblueprint">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The <blueprint> element is the root element for a blueprint
                configuration file.  A blueprint configuration has two sections.
                The first section (contained within the <type-converters> element)
                identifies components that are used for converting values into
                different target types.  The type converters are optional, so
                the file does not need to specify a type converter section.

                Following the type converters are the component definitions.
                Components are <bean>, <service>, <reference>, and
                <reference-list> elements that identify the bundle components that will
                be managed by the blueprint service.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:complexType name="Tblueprint">
        <xsd:sequence>
            <xsd:element name="description" type="Tdescription"
                minOccurs="0" />
            <xsd:element name="type-converters" type="Ttype-converters"
                minOccurs="0" maxOccurs="1" />
            <!-- top-level components -->
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element name="service" type="Tservice" />
                <xsd:element name="reference-list" type="Treference-list" />
                <xsd:element name="bean" type="Tbean" />
                <xsd:element name="reference" type="Treference" />
                <xsd:any namespace="##other" processContents="lax" />
            </xsd:choice>
        </xsd:sequence>

        <!-- Defaults-->
        <xsd:attribute name="default-activation" default="eager"
            type="Tactivation">
            <xsd:annotation>
                <xsd:documentation>
                    <![CDATA[
                    Specifies the default activation setting that will be defined
                    for components.  If not specified, the global default is "eager".
                    Individual components may override the default value.
                    ]]>
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="default-timeout" type="Ttimeout"
            default="300000">
            <xsd:annotation>
                <xsd:documentation>
                    <![CDATA[
                    Specifies the default timeout value to be used when operations
                    are invoked on unstatisfied service references.  If the
                    reference does not change to a satisfied state within the timeout
                    window, an error is raised on the method invocation.  The
                    default timeout value is 300000 milliseconds and individual
                    <reference> element can override the specified configuration
                    default.
                    ]]>
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="default-availability" type="Tavailability"
            default="mandatory">
            <xsd:annotation>
                <xsd:documentation>
                    <![CDATA[
                    Specifies the default availability value to be used for
                    <reference>, and <reference-list> components.  The
                    normal default is "mandatory", and can be changed by individual
                    service reference components.
                    ]]>
                </xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:anyAttribute namespace="##other"
            processContents="lax" />
    </xsd:complexType>

    <xsd:complexType name="Ttype-converters">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The type used for the <type-converters> element.  The
                <type-converters> section is a set of <bean>, <ref>, or
                <reference> elements that identify the type converter components.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
            <xsd:element name="bean" type="Tbean" />
            <xsd:element name="reference" type="Treference" />
            <xsd:element name="ref" type="Tref" />
            <xsd:any namespace="##other" processContents="lax" />
        </xsd:choice>
    </xsd:complexType>

    <!--
        Components that provide a reasonable target for injection used for
        listeners, etc.
    -->

    <xsd:group name="GtargetComponent">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                A target component is one that can be a target for a
                listener, registration-listener or service elements.
                This is used in contexts where the requirement is a single
                provided object that will implement a particular interface.
                The provided object is obtained either from a <ref> element
                or an inlined <bean> or <reference>.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice>
            <xsd:element name="bean" type="Tinlined-bean" />
            <xsd:element name="reference" type="Tinlined-reference" />
            <xsd:element name="ref" type="Tref" />
            <xsd:any namespace="##other" processContents="lax" />
        </xsd:choice>
    </xsd:group>

    <xsd:group name="GallComponents">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                An all components is used in contexts where all component element
                types are values.  The set of component elements contains
                <bean>, <service>, <reference>, <reference-list> and <ref>.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice>
            <xsd:element name="service" type="Tinlined-service" />
            <xsd:element name="reference-list" type="Tinlined-reference-list" />
            <xsd:group ref="GtargetComponent" />
        </xsd:choice>
    </xsd:group>

    <xsd:group name="GbeanElements">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                A bean elements is a reusable definition of the elements allowed on 
                a <bean> element.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="description" type="Tdescription"
                minOccurs="0" />
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element name="argument" type="Targument" />
                <xsd:element name="property" type="Tproperty" />
                <xsd:any namespace="##other" processContents="lax" />
            </xsd:choice>
        </xsd:sequence>
    </xsd:group>

    <xsd:complexType name="Tbean">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The type definition for a <bean> component.  The <bean> 
                attributes provide the characteristics for how to create a
                bean instance.  Constructor arguments and injected properties
                are specified via child <argument> and <property> elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="Tcomponent">
                <xsd:group ref="GbeanElements" />
                <xsd:attribute name="class" type="Tclass" />
                <xsd:attribute name="init-method" type="Tmethod" />
                <xsd:attribute name="destroy-method" type="Tmethod" />
                <xsd:attribute name="factory-method" type="Tmethod" />
                <xsd:attribute name="factory-ref" type="Tidref" />
                <xsd:attribute name="scope" type="Tscope" />
                <xsd:anyAttribute namespace="##other"
                    processContents="lax" />
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="Tinlined-bean">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The Tinlined-bean type is used for inlined (i.e. non top level)
                <bean> elements.  Those elements have some restrictions on
                the attributes that can be used to define them.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:restriction base="Tbean">
                <xsd:group ref="GbeanElements" />
                <xsd:attribute name="id" use="prohibited" />
                <xsd:attribute name="depends-on" type="TdependsOn" />
                <xsd:attribute name="activation" use="prohibited"
                    fixed="lazy" />
                <xsd:attribute name="class" type="Tclass" />
                <xsd:attribute name="init-method" type="Tmethod" />
                <xsd:attribute name="destroy-method" use="prohibited" />
                <xsd:attribute name="factory-method" type="Tmethod" />
                <xsd:attribute name="factory-ref" type="Tidref" />
                <xsd:attribute name="scope" use="prohibited" />
                <xsd:anyAttribute namespace="##other"
                    processContents="lax" />
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="Targument">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                An argument used to create an object defined by a <bean>
                component.  The <argument> elements are the arguments for the
                bean class constructor or passed to the bean factory method.

                The type, if specified, is used to disambiguate the constructor
                or method signature.  Arguments may also be matched up with
                arguments by explicitly specifying the index position.  If the
                index is used, then all <argument> elements for the bean must
                also specify the index.

                The value and ref attributes are convenience shortcuts to make
                the <argument> tag easier to code.  A fuller set of injected
                values and types can be specified using one of the "value"
                type elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="description" type="Tdescription"
                minOccurs="0" />
            <xsd:group ref="Gvalue" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="index" type="xsd:nonNegativeInteger" />
        <xsd:attribute name="type" type="Ttype" />
        <xsd:attribute name="ref" type="Tidref" />
        <xsd:attribute name="value" type="TstringValue" />
    </xsd:complexType>

    <xsd:complexType name="Tproperty">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                A property that will be injected into a created <bean>
                component.  The <property> elements correspond to named
                JavaBean setting methods for a created bean object.

                The value and ref attributes are convenience shortcuts to make
                the <argument> tag easier to code.  A fuller set of injected
                values and types can be specified using one of the "value"
                type elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="description" type="Tdescription"
                minOccurs="0" />
            <xsd:group ref="Gvalue" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="name" type="Tmethod" use="required" />
        <xsd:attribute name="ref" type="Tidref" />
        <xsd:attribute name="value" type="TstringValue" />
    </xsd:complexType>

    <xsd:complexType name="Tkey">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The Tkey type defines the element types that are permitted
                for Map key situations.  These can be any of the "value"
                types other than the <null> element.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:group ref="GnonNullValue" />
    </xsd:complexType>

    <!-- reference -->
    <xsd:complexType name="Treference">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The Treference type defines the <reference> element.  These
                are instances of the TserviceReference type, with the addition
                of a timeout attribute.  If the timeout is not specified,
                the default-timeout value is inherited from the encapsulating
                <blueprint> definition.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="TserviceReference">
                <xsd:sequence>
                    <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
                        processContents="lax" />
                </xsd:sequence>
                <xsd:attribute name="timeout" type="Ttimeout" />
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="Tinlined-reference">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The Tinlined-reference type is used for inlined (i.e. non top level)
                <reference> elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:restriction base="Treference">
                <xsd:sequence>
                    <xsd:group ref="GserviceReferenceElements" />
                    <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
                        processContents="lax" />
                </xsd:sequence>
                <xsd:attribute name="id" use="prohibited" />
                <xsd:attribute name="depends-on" type="TdependsOn" />
                <xsd:attribute name="activation" use="prohibited"
                    fixed="lazy" />
                <xsd:attribute name="interface" type="Tclass" />
                <xsd:attribute name="filter" type="xsd:normalizedString" />
                <xsd:attribute name="component-name" type="Tidref" />
                <xsd:attribute name="availability" type="Tavailability" />
                <xsd:attribute name="timeout" type="Ttimeout" />
                <xsd:anyAttribute namespace="##other"
                    processContents="lax" />
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- reference-list -->
    <xsd:complexType name="Treference-list">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The Treference-list builds in the characteristics of the
                TserviceReference type to define characteristics of the
                <reference-list>.  This adds in the characteristics that
                only apply to collections of references (e.g., member-type).
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="TserviceReference">
                <xsd:sequence>
                    <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
                        processContents="lax" />
                </xsd:sequence>
                <xsd:attribute name="member-type" type="Tservice-use"
                    default="service-object">
                </xsd:attribute>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="Tinlined-reference-list">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The Tinlined-reference-list type is used for inlined (i.e. non top level)
                <reference-list> elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:restriction base="Treference-list">
                <xsd:sequence>
                    <xsd:group ref="GserviceReferenceElements" />
                    <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
                        processContents="lax" />
                </xsd:sequence>
                <xsd:attribute name="id" use="prohibited" />
                <xsd:attribute name="depends-on" type="TdependsOn" />
                <xsd:attribute name="activation" use="prohibited"
                    fixed="lazy" />
                <xsd:attribute name="interface" type="Tclass" />
                <xsd:attribute name="filter" type="xsd:normalizedString" />
                <xsd:attribute name="component-name" type="Tidref" />
                <xsd:attribute name="availability" type="Tavailability" />
                <xsd:attribute name="member-type" type="Tservice-use"
                    default="service-object" />
                <xsd:anyAttribute namespace="##other"
                    processContents="lax" />
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- Reference base class -->
    <xsd:complexType name="TserviceReference">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TserviceReference is the base element type used for <reference>
                and <reference-list> elements.  This type defines all of the
                characteristics common to both sorts of references.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="Tcomponent">
                <xsd:sequence>
                    <xsd:group ref="GserviceReferenceElements" />
                </xsd:sequence>

                <xsd:attribute name="interface" type="Tclass">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            The interface that the OSGi service must implement and that will be
                            implemented by the proxy object.
                            This attribute is optional.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="filter" type="xsd:normalizedString">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            A filter string used to narrow the search for a matching service
                            reference.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="component-name" type="Tidref">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            An optional specifier that can be used to match a service definition
                            to one created by a specific blueprint component.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="availability" type="Tavailability">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            Use to control the initial processing of service references at
                            blueprint context startup.  "mandatory" indicates the context
                            should not start unless the service is available within the
                            specified context startup period.  "optional" indicates availability
                            of this service is not a requirement at bundle startup.

                            NOTE:  No default is specified because this can be overridden
                            by the default-availability attribute of the <blueprint> element.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:anyAttribute namespace="##other"
                    processContents="lax" />
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:group name="GserviceReferenceElements">
        <xsd:sequence>
            <xsd:element name="description" type="Tdescription"
                minOccurs="0" />
            <!-- listener -->
            <xsd:element name="reference-listener" type="TreferenceListener"
                minOccurs="0" maxOccurs="unbounded">
                <xsd:annotation>
                    <xsd:documentation>
                        <![CDATA[
                        A definition of a listener that will watch for bind/unbind events
                        associated with the service reference.  The targetted listener can
                        be a <ref> to a <bean> or <reference> element, or an inline
                        <bean> or <reference>.
                        ]]>
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:element>
        </xsd:sequence>
    </xsd:group>

    <xsd:complexType name="TreferenceListener">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TReferenceListener defines a reference listener that is attached
                to a <reference> or <reference-list> element.  The listener
                object can be specified as a <ref> or as an inline <bean> or
                <reference> component.  Listener events are mapped to the indicated
                bind or unbind methods.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:group ref="GtargetComponent" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="ref" type="Tidref" />
        <xsd:attribute name="bind-method" type="Tmethod" />
        <xsd:attribute name="unbind-method" type="Tmethod" />
    </xsd:complexType>

    <xsd:simpleType name="Tactivation">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tactivation defines the activation type for components.  This is used in this
                schema by the <blueprint> default-activation attribute and the
                activation attribute.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="eager" />
            <xsd:enumeration value="lazy" />
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="Tavailability">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tavailability defines an availability attribute type.  This is used in this
                schema by the <blueprint> default-availability attribute and the
                <reference> and <reference-list> availability attribute.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="mandatory" />
            <xsd:enumeration value="optional" />
        </xsd:restriction>
    </xsd:simpleType>

    <!-- service -->

    <xsd:complexType name="Tservice">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tservice is the type for services exported by this blueprint bundle.
                Services are sourced by either a <ref> to a <bean> component or an
                <inline> bean component.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="Tcomponent">
                <xsd:sequence>
                    <xsd:group ref="GserviceElements" />
                </xsd:sequence>
                <xsd:attribute name="interface" type="Tclass">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            The interface that this OSGi service will provide.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="ref" type="Tidref">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            The ref attribute can be used to specify the component that provides
                            the object exported as an OSGi service.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="auto-export" type="TautoExportModes"
                    default="disabled">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            If set to a value different from "disabled", the Blueprint Container
                            will introspect the target to discover the set of interfaces or classes
                            that the service will be registered under.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="ranking" type="xsd:int" default="0">
                    <xsd:annotation>
                        <xsd:documentation>
                            <![CDATA[
                            A service ranking value that is added to the service properties
                            the service will be published with.
                            ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:anyAttribute namespace="##other"
                    processContents="lax" />
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="Tinlined-service">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The Tinlined-service type is used for inlined (i.e. non top level)
                <service> elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:restriction base="Tservice">
                <xsd:sequence>
                    <xsd:group ref="GserviceElements" />
                </xsd:sequence>
                <xsd:attribute name="id" use="prohibited" />
                <xsd:attribute name="depends-on" type="TdependsOn" />
                <xsd:attribute name="activation" use="prohibited"
                    fixed="lazy" />
                <xsd:attribute name="interface" type="Tclass" />
                <xsd:attribute name="ref" type="Tidref" />
                <xsd:attribute name="auto-export" type="TautoExportModes"
                    default="disabled" />
                <xsd:attribute name="ranking" type="xsd:int" default="0" />
                <xsd:anyAttribute namespace="##other"
                    processContents="lax" />
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:group name="GbaseServiceElements">
        <xsd:sequence>
            <xsd:element name="description" type="Tdescription"
                minOccurs="0" />
            <xsd:element name="interfaces" type="Tinterfaces"
                minOccurs="0">
                <xsd:annotation>
                    <xsd:documentation>
                        <![CDATA[
                        A collection of one or more interface class names this service
                        will be registered under.  The <service> element also has
                        a shortcut interface attribute for the usual case of just
                        a single interface being used.  This also cannot be used if
                        the auto-export attribute is used.
                        ]]>
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:element>

            <xsd:element name="service-properties" type="TserviceProperties"
                minOccurs="0">
                <xsd:annotation>
                    <xsd:documentation>
                        <![CDATA[
                        The service provided when the service is registered.  The service
                        properties are similar to map elements, but the keys must always
                        be strings, and the values are required to be in a narrower range.
                        ]]>
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:element>
            <xsd:element name="registration-listener" type="TregistrationListener"
                minOccurs="0" maxOccurs="unbounded">
                <xsd:annotation>
                    <xsd:documentation>
                        <![CDATA[
                        A set of 0 or more registration listeners attached to this service
                        component.  The registration listeners will be notified whenever the
                        service is registered or unregistered from the framework service
                        registry.
                        ]]>
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:element>
        </xsd:sequence>
    </xsd:group>

    <xsd:group name="GserviceElements">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                A set of service elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:group ref="GbaseServiceElements" />
            <xsd:group ref="GtargetComponent" minOccurs="0">
                <xsd:annotation>
                    <xsd:documentation>
                        <![CDATA[
                        A service definition can use any of the target types as an inline element
                        as well.
                        ]]>
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:group>
        </xsd:sequence>
    </xsd:group>

    <xsd:complexType name="TregistrationListener">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                A registration listener definition.  The target registration listener
                can be either a <ref> to a <bean> or <service> component, or an inline
                <bean> or <service> component definition.  The registration-method and
                unregistration-method attributes define the methods that will be called
                for the respective events.

                For the very common case of using a <ref> to a listener component, the
                ref attribute may also be used as a shortcut.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:group ref="GtargetComponent" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="ref" type="Tidref" />
        <xsd:attribute name="registration-method" type="Tmethod" />
        <xsd:attribute name="unregistration-method" type="Tmethod" />
    </xsd:complexType>

    <!-- Values -->

    <xsd:group name="Gvalue">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The set of "value" types that can be used in any place a value
                can be specified.  This set includes the <ref> and <idref> elements, any of the
                component types (<bean>, <service>, etc.) as inline components, the
                generic <value> element for types sourced from string values, any of the
                collection types (<set>, <list>, <array>, <map>, <props>), and the
                <null> type to inject a null value.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice>
            <xsd:group ref="GnonNullValue" />
            <xsd:element name="null" type="Tnull" />
        </xsd:choice>
    </xsd:group>

    <xsd:complexType name="Tnull">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The definition for a <null> value type.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
    </xsd:complexType>

    <xsd:group name="GnonNullValue">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The set of "value" types that can be used in any place a non-null value
                can be specified.  This set includes the <ref> and <idref> elements, any of the
                component types (<bean>, <service>, etc.) as inline components, the
                generic <value> element for types sourced from string values, and any of the
                collection types (<set>, <list>, <array>, <map>, <props>).

                The <null> type is NOT a member of this group.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice>
            <xsd:group ref="GallComponents" />
            <xsd:element name="idref" type="Tref" />
            <xsd:element name="value" type="Tvalue" />
            <xsd:element name="list" type="Tcollection" />
            <xsd:element name="set" type="Tcollection" />
            <xsd:element name="map" type="Tmap" />
            <xsd:element name="array" type="Tcollection" />
            <xsd:element name="props" type="Tprops" />
        </xsd:choice>
    </xsd:group>

    <xsd:complexType name="Tref">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tref is the type used for <ref> elements.  This specifies a required
                component id for the reference component.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="component-id" type="Tidref" use="required" />
    </xsd:complexType>

    <xsd:complexType name="Tvalue" mixed="true">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tvalue is the type used for <value> elements.  The <value> element
                is used for types that can be created from a single string value.
                The string value is the data value for the element.  The optional
                type attribute allows a target conversion value to be explicitly
                specified.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="type" type="Ttype" />
    </xsd:complexType>

    <!-- Collection Values -->

    <xsd:complexType name="TtypedCollection">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TtypeCollection defines comment attributes shared among different
                collection types that allow a default value type to be specified.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="value-type" type="Ttype" />
    </xsd:complexType>

    <xsd:complexType name="Tcollection">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tcollection is the base schema type for different ordered collection
                types.  This is shared between the <array>, <list>, and <set> elements.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="TtypedCollection">
                <xsd:group ref="Gvalue" minOccurs="0" maxOccurs="unbounded" />
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="Tprops">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tprops is the type used by the <props> value element.  The prop elements
                are pairs of string-valued keys and values.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="prop" type="Tprop" minOccurs="0"
                maxOccurs="unbounded" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="Tprop" mixed="true">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tprop is a single property element for a <props> value type.  The property
                value can be specified using either the attribute, or as value data for
                the property element.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:attribute name="key" type="TstringValue" use="required" />
        <xsd:attribute name="value" type="TstringValue" />
    </xsd:complexType>

    <!-- 'map' element type -->
    <xsd:complexType name="Tmap">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tmap is the base type used for <map> elements.  A map may have a
                default value type specified, so it inherits from the TtypeCollection
                type.  A key type can also be specified, and the map members are
                created from the entry elements, which require a key/value pair.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:complexContent>
            <xsd:extension base="TtypedCollection">
                <xsd:sequence>
                    <xsd:element name="entry" type="TmapEntry" minOccurs="0"
                        maxOccurs="unbounded" />
                </xsd:sequence>
                <xsd:attribute name="key-type" type="Ttype" />
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <!-- 'entry' element type -->
    <xsd:complexType name="TmapEntry">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TmapEntry is used for <entry> elements nested inside of a <map> element.
                Each <entry> instance defines a key/value pair that will be added to the
                Map.  Both the keys and values may be arbitrary types.  Keys must not
                be <null> but <null> is permitted for entry values.  A default type
                can be specified for both the keys and the values, but individual keys
                or values can override the default.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="key" type="Tkey" minOccurs="0" />
            <xsd:group ref="Gvalue" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="key" type="TstringValue" />
        <xsd:attribute name="key-ref" type="Tidref" />
        <xsd:attribute name="value" type="TstringValue" />
        <xsd:attribute name="value-ref" type="Tidref" />
    </xsd:complexType>

    <!-- 'service property' element type -->
    <xsd:complexType name="TserviceProperties">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TserviceProperty is used for <service-properties> elements.
                The syntax is similar to what is defined for <map>, but keys must be
                string values and there are no type defaults that can be specified.
                created from the entry elements, which require a key/value pair.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:element name="entry" type="TservicePropertyEntry"
                minOccurs="0" maxOccurs="unbounded" />
            <xsd:any namespace="##other" processContents="lax"
                minOccurs="0" maxOccurs="unbounded" />
        </xsd:sequence>
    </xsd:complexType>

    <!-- 'entry' element type -->
    <xsd:complexType name="TservicePropertyEntry">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TservicePropertyEntry is an entry value used for the <service-properties>
                element.  This does not allow a child <key> element and there are no
                key-ref or value-ref attributes.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:sequence>
            <xsd:group ref="Gvalue" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="key" type="TstringValue" use="required" />
        <xsd:attribute name="value" type="TstringValue" />
    </xsd:complexType>

    <!-- General types -->

    <xsd:complexType name="Tdescription" mixed="true">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                A generic <description> element type to allow documentation to added to the
                blueprint configuration.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice minOccurs="0" maxOccurs="unbounded" />
    </xsd:complexType>

    <xsd:complexType name="Tinterfaces">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                The type definition for the <interfaces> element used for <service>
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice minOccurs="1" maxOccurs="unbounded">
            <xsd:element name="value" type="TinterfaceValue" />
        </xsd:choice>
    </xsd:complexType>

    <xsd:simpleType name="TinterfaceValue">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TinterfaceValue is used for subelements of the <interfaces> element.
                This is just a <value>xxxxx</value> element where the contained
                value is the name of an interface class.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="Tclass" />
    </xsd:simpleType>

    <xsd:simpleType name="Tclass">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tclass is a base type that should be used for all attributes that
                refer to java class names.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:NCName" />
    </xsd:simpleType>

    <xsd:simpleType name="Ttype">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Ttype is a base type that refer to java types such as classes or
                arrays.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:token">
            <xsd:pattern value="[\i-[:]][\c-[:]]*(\[\])*" />
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="Tmethod">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tmethod is a base type that should be used for all attributes that
                refer to java method names.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:NCName" />
    </xsd:simpleType>

    <!--
        Should be used for all attributes and elements that refer to method
        names
    -->
    <xsd:simpleType name="Tidref">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Tidref is a base type that should be used for all attributes that
                refer to component ids.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:NCName" />
    </xsd:simpleType>

    <xsd:simpleType name="TstringValue">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TstringValue is a base type that should be used for all attributes that
                refer to raw string values
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:normalizedString" />
    </xsd:simpleType>

    <xsd:simpleType name="TautoExportModes">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TautoExportModes is a base type that should be used for export-mode
                attributes.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="disabled" />
            <xsd:enumeration value="interfaces" />
            <xsd:enumeration value="class-hierarchy" />
            <xsd:enumeration value="all-classes" />
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="Ttimeout">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Ttimeout is a base type that should be used for all attributes that
                specify timeout values
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:unsignedLong" />
    </xsd:simpleType>

    <xsd:simpleType name="TdependsOn">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                TdependsOn is a base type that should be used for all attributes that
                specify depends-on relationships
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction>
            <xsd:simpleType>
                <xsd:list itemType="Tidref" />
            </xsd:simpleType>
            <xsd:minLength value="1" />
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="Tscope">
        <xsd:union>
            <xsd:simpleType>
                <xsd:restriction base="xsd:NMTOKEN">
                    <xsd:enumeration value="singleton" />
                    <xsd:enumeration value="prototype" />
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType>
                <xsd:restriction base="xsd:QName">
                    <xsd:pattern value=".+:.+" />
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:union>
    </xsd:simpleType>

    <xsd:simpleType name="Tservice-use">
        <xsd:annotation>
            <xsd:documentation>
                <![CDATA[
                Indicates the type of object that will be placed within the
                reference collection.  "service-object" indicates the 
                collection contains blueprint proxies for imported services.  
                "service-reference" indicates the collection contains 
                ServiceReference objects matching the target service type.
                ]]>
            </xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="service-object" />
            <xsd:enumeration value="service-reference" />
        </xsd:restriction>
    </xsd:simpleType>

</xsd:schema>

121.16 Security

121.16.1 Blueprint Extender

A Blueprint Extender must use the Bundle Context of the Blueprint bundle. This will ensure that much of the resources allocated will be used on behalf of the Blueprint bundle. However, most Java 2 permissions will also verify the stack and this will inevitably include the Blueprint extender's code. Therefore, the Blueprint extender will require the combined set of permissions needed by all Blueprint bundles. It is therefore likely that in practical situations the Blueprint extender requires All Permission.

The Blueprint bundle requires permission for all actions that are done by the Blueprint Container on behalf of this bundle. That is, the Blueprint Container must not give any extra permissions to the Blueprint bundle because it is being extended.

A Blueprint Container must therefore use a doPriviliged block around all actions that execute code on behalf of the Blueprint bundle. This doPrivileged block must use an Access Control Context that represents the permissions of the Blueprint bundle.

For example, if a Blueprint bundle defines the following bean:

<bean class="java.lang.System" factory-method="exit">
    <argument value="1"/>
</bean>

Then the Blueprint bundle must have the proper permission to exit the system or the Blueprint bundle must fail when the bean is constructed. At the same time, a Blueprint bundle must not be required to have any permission needed by the Blueprint Container to performs its tasks.

A Blueprint Container must never use the setAccessibility method on a returned member. Only publicly accessible members must be used. Using a non-publicly accessible member must initiate failure, resulting in the destruction of the container.

121.16.2 Blueprint Bundle

A Blueprint Bundle must have all the permissions required by its code. There is one additional permission required for the Blueprint Bundle. The Blueprint extender will register a Blueprint Container service on behalf of the Blueprint bundle, and the Blueprint bundle must therefore have:

ServicePermission(...BlueprintContainer,[REGISTER])

121.17 org.osgi.service.blueprint.container

Version 1.0

Blueprint Container Package Version 1.0.

This package defines the primary interface to a Blueprint Container, BlueprintContainer. An instance of this type is available inside a Blueprint Container as an implicitly defined component with the name "blueprintContainer".

This package also declares the supporting exception types, listener, and constants for working with a Blueprint Container.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.blueprint.container; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.blueprint.container; version="[1.0,1.1)"

121.17.1 Summary

121.17.2 public interface BlueprintContainer

A Blueprint Container represents the managed state of a Blueprint bundle. A Blueprint Container provides access to all managed components. These are the beans, services, and service references. Only bundles in the ACTIVE state (and also the STARTING state for bundles awaiting lazy activation) can have an associated Blueprint Container. A given Bundle Context has at most one associated Blueprint Container. A Blueprint Container can be obtained by injecting the predefined "blueprintContainer" component id. The Blueprint Container is also registered as a service and its managed components can be queried.

Thread-safe

Consumers of this API must not implement this type

121.17.2.1 public Set<String> getComponentIds()

Returns the set of component ids managed by this Blueprint Container.

An immutable Set of Strings, containing the ids of all of the components managed within this Blueprint Container.

121.17.2.2 public Object getComponentInstance(String id)

The component id for the requested component instance.

Return the component instance for the specified component id. If the component's manager has not yet been activated, calling this operation will atomically activate it. If the component has singleton scope, the activation will cause the component instance to be created and initialized. If the component has prototype scope, then each call to this method will return a new component instance.

A component instance for the component with the specified component id.

NoSuchComponentException– If no component with the specified component id is managed by this Blueprint Container.

121.17.2.3 public ComponentMetadata getComponentMetadata(String id)

The component id for the requested Component Metadata.

Return the Component Metadata object for the component with the specified component id.

The Component Metadata object for the component with the specified component id.

NoSuchComponentException– If no component with the specified component id is managed by this Blueprint Container.

121.17.2.4 public Collection<T> getMetadata(Class<T> type)

<T extends ComponentMetadata>

Type of Component Metadata.

The super type or type of the requested Component Metadata objects.

Return all ComponentMetadata objects of the specified Component Metadata type. The supported Component Metadata types are ComponentMetadata (which returns the Component Metadata for all defined manager types), BeanMetadata , ServiceReferenceMetadata (which returns both ReferenceMetadata and ReferenceListMetadata objects), and ServiceMetadata. The collection will include all Component Metadata objects of the requested type, including components that are declared inline.

An immutable collection of Component Metadata objects of the specified type.

121.17.3 public class BlueprintEvent

A Blueprint Event.

BlueprintEvent objects are delivered to all registered BlueprintListener services. Blueprint Events must be asynchronously delivered in chronological order with respect to each listener.

In addition, after a Blueprint Listener is registered, the Blueprint extender will synchronously send to this Blueprint Listener the last Blueprint Event for each ready Blueprint bundle managed by this extender. This replay of Blueprint Events is designed so that the new Blueprint Listener can be informed of the state of each Blueprint bundle. Blueprint Events sent during this replay will have the isReplay() flag set. The Blueprint extender must ensure that this replay phase does not interfere with new Blueprint Events so that the chronological order of all Blueprint Events received by the Blueprint Listener is preserved. If the last Blueprint Event for a given Blueprint bundle is DESTROYED, the extender must not send it during this replay phase.

A type code is used to identify the type of event. The following event types are defined:

In addition to calling the registered BlueprintListener services, the Blueprint extender must also send those events to the Event Admin service, if it is available.

BlueprintListener, EventConstants

Immutable

121.17.3.1 public static final int CREATED = 2

The Blueprint extender has created a Blueprint Container for the bundle. This event is sent after the Blueprint Container has been registered as a service.

121.17.3.2 public static final int CREATING = 1

The Blueprint extender has started creating a Blueprint Container for the bundle.

121.17.3.3 public static final int DESTROYED = 4

The Blueprint Container for the bundle has been completely destroyed. This event is sent after the Blueprint Container has been unregistered as a service.

121.17.3.4 public static final int DESTROYING = 3

The Blueprint extender has started destroying the Blueprint Container for the bundle.

121.17.3.5 public static final int FAILURE = 5

The Blueprint Container creation for the bundle has failed. If this event is sent after a timeout in the Grace Period, the getDependencies() method must return an array of missing mandatory dependencies. The event must also contain the cause of the failure as a Throwable through the getCause() method.

121.17.3.6 public static final int GRACE_PERIOD = 6

The Blueprint Container has entered the grace period. The list of missing dependencies must be made available through the getDependencies() method. During the grace period, a GRACE_PERIOD event is sent each time the set of unsatisfied dependencies changes.

121.17.3.7 public static final int WAITING = 7

The Blueprint Container is waiting on the availability of a service to satisfy an invocation on a referenced service. The missing dependency must be made available through the getDependencies() method which will return an array containing one filter object as a String.

121.17.3.8 public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle)

The type of this event.

The Blueprint bundle associated with this event. This parameter must not be null.

The Blueprint extender bundle that is generating this event. This parameter must not be null.

Create a simple BlueprintEvent object.

121.17.3.9 public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle, String[] dependencies)

The type of this event.

The Blueprint bundle associated with this event. This parameter must not be null.

The Blueprint extender bundle that is generating this event. This parameter must not be null.

An array of String filters for each dependency associated with this event. Must be a non-empty array for event types GRACE_PERIOD and WAITING. It is optional for event type FAILURE. Must be null for other event types.

Create a BlueprintEvent object associated with a set of dependencies.

121.17.3.10 public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle, Throwable cause)

The type of this event.

The Blueprint bundle associated with this event. This parameter must not be null.

The Blueprint extender bundle that is generating this event. This parameter must not be null.

A Throwable object describing the root cause of the event. May be null.

Create a BlueprintEvent object associated with a failure cause.

121.17.3.11 public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle, String[] dependencies, Throwable cause)

The type of this event.

The Blueprint bundle associated with this event. This parameter must not be null.

The Blueprint extender bundle that is generating this event. This parameter must not be null.

An array of String filters for each dependency associated with this event. Must be a non-empty array for event types GRACE_PERIOD and WAITING. It is optional for event type FAILURE. Must be null for other event types.

A Throwable object describing the root cause of this event. May be null.

Create a BlueprintEvent object associated with a failure cause and a set of dependencies.

121.17.3.12 public BlueprintEvent(BlueprintEvent event, boolean replay)

The original BlueprintEvent to copy. Must not be null.

true if this event should be used as a replay event.

Create a new BlueprintEvent from the specified BlueprintEvent. The timestamp property will be copied from the original event and only the replay property will be overridden with the given value.

121.17.3.13 public Bundle getBundle()

Return the Blueprint bundle associated with this event.

The Blueprint bundle associated with this event.

121.17.3.14 public Throwable getCause()

Return the cause for this FAILURE event.

The cause of the failure for this event. May be null .

121.17.3.15 public String[] getDependencies()

Return the filters identifying the missing dependencies that caused this event.

The filters identifying the missing dependencies that caused this event if the event type is one of WAITING, GRACE_PERIOD or FAILURE or null for the other event types.

121.17.3.16 public Bundle getExtenderBundle()

Return the Blueprint extender bundle that is generating this event.

The Blueprint extender bundle that is generating this event.

121.17.3.17 public long getTimestamp()

Return the time at which this event was created.

The time at which this event was created.

121.17.3.18 public int getType()

Return the type of this event.

The type values are:

The type of this event.

121.17.3.19 public boolean isReplay()

Return whether this event is a replay event.

true if this event is a replay event and false otherwise.

121.17.4 public interface BlueprintListener

A BlueprintEvent Listener.

To receive Blueprint Events, a bundle must register a Blueprint Listener service. After a Blueprint Listener is registered, the Blueprint extender must synchronously send to this Blueprint Listener the last Blueprint Event for each ready Blueprint bundle managed by this extender. This replay of Blueprint Events is designed so that the new Blueprint Listener can be informed of the state of each Blueprint bundle. Blueprint Events sent during this replay will have the isReplay() flag set. The Blueprint extender must ensure that this replay phase does not interfere with new Blueprint Events so that the chronological order of all Blueprint Events received by the Blueprint Listener is preserved. If the last Blueprint Event for a given Blueprint bundle is DESTROYED, the extender must not send it during this replay phase.

BlueprintEvent

Thread-safe

121.17.4.1 public void blueprintEvent(BlueprintEvent event)

The BlueprintEvent.

Receives notifications of a Blueprint Event. Implementers should quickly process the event and return.

121.17.5 public class ComponentDefinitionException
extends RuntimeException

A Blueprint exception indicating that a component definition is in error. This exception is thrown when a configuration-related error occurs during creation of a Blueprint Container.

121.17.5.1 public ComponentDefinitionException()

Creates a Component Definition Exception with no message or exception cause.

121.17.5.2 public ComponentDefinitionException(String explanation)

The associated message.

Creates a Component Definition Exception with the specified message

121.17.5.3 public ComponentDefinitionException(String explanation, Throwable cause)

The associated message.

The cause of this exception.

Creates a Component Definition Exception with the specified message and exception cause.

121.17.5.4 public ComponentDefinitionException(Throwable cause)

The cause of this exception.

Creates a Component Definition Exception with the exception cause.

121.17.6 public interface Converter

Type converter to convert an object to a target type.

Thread-safe

121.17.6.1 public boolean canConvert(Object sourceObject, ReifiedType targetType)

The source object s to convert.

The target type T.

Return if this converter is able to convert the specified object to the specified type.

true if the conversion is possible, false otherwise.

121.17.6.2 public Object convert(Object sourceObject, ReifiedType targetType) throws Exception

The source object s to convert.

The target type T.

Convert the specified object to an instance of the specified type.

An instance with a type that is assignable from targetType's raw class

Exception– If the conversion cannot succeed. This exception should not be thrown when the canConvert method has returned true.

121.17.7 public class EventConstants

Event property names used in Event Admin events published by a Blueprint Container.

Each type of event is sent to a different topic:

org/osgi/service/blueprint/container/ <event-type>

where <event-type> can have the values CREATING, CREATED, DESTROYING, DESTROYED, FAILURE, GRACE_PERIOD, or WAITING.

Such events have the following properties:

Immutable

121.17.7.1 public static final String BUNDLE = "bundle"

The Blueprint bundle associated with this event. This property is of type Bundle.

121.17.7.2 public static final String BUNDLE_ID = "bundle.id"

The bundle id of the Blueprint bundle associated with this event. This property is of type Long.

121.17.7.3 public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName"

The bundle symbolic name of the Blueprint bundle associated with this event. This property is of type String.

121.17.7.4 public static final String BUNDLE_VERSION = "bundle.version"

The bundle version of the Blueprint bundle associated with this event. This property is of type Version.

121.17.7.5 public static final String CAUSE = "cause"

The cause for a FAILURE event. This property is of type Throwable.

121.17.7.6 public static final String DEPENDENCIES = "dependencies"

The filters identifying the missing dependencies that caused this event for a FAILURE, GRACE_PERIOD, or WAITING event. This property type is an array of String.

121.17.7.7 public static final String EVENT = "event"

The BlueprintEvent object that caused this event. This property is of type BlueprintEvent.

121.17.7.8 public static final String EXTENDER_BUNDLE = "extender.bundle"

The Blueprint extender bundle that is generating this event. This property is of type Bundle.

121.17.7.9 public static final String EXTENDER_BUNDLE_ID = "extender.bundle.id"

The bundle id of the Blueprint extender bundle that is generating this event. This property is of type Long.

121.17.7.10 public static final String EXTENDER_BUNDLE_SYMBOLICNAME = "extender.bundle.symbolicName"

The bundle symbolic of the Blueprint extender bundle that is generating this event. This property is of type String.

121.17.7.11 public static final String EXTENDER_BUNDLE_VERSION = "extender.bundle.version"

The bundle version of the Blueprint extender bundle that is generating this event. This property is of type Version.

121.17.7.12 public static final String TIMESTAMP = "timestamp"

The time the event was created. This property is of type Long.

121.17.7.13 public static final String TOPIC_BLUEPRINT_EVENTS = "org/osgi/service/blueprint/container"

Topic prefix for all events issued by the Blueprint Container

121.17.7.14 public static final String TOPIC_CREATED = "org/osgi/service/blueprint/container/CREATED"

Topic for Blueprint Container CREATED events

121.17.7.15 public static final String TOPIC_CREATING = "org/osgi/service/blueprint/container/CREATING"

Topic for Blueprint Container CREATING events

121.17.7.16 public static final String TOPIC_DESTROYED = "org/osgi/service/blueprint/container/DESTROYED"

Topic for Blueprint Container DESTROYED events

121.17.7.17 public static final String TOPIC_DESTROYING = "org/osgi/service/blueprint/container/DESTROYING"

Topic for Blueprint Container DESTROYING events

121.17.7.18 public static final String TOPIC_FAILURE = "org/osgi/service/blueprint/container/FAILURE"

Topic for Blueprint Container FAILURE events

121.17.7.19 public static final String TOPIC_GRACE_PERIOD = "org/osgi/service/blueprint/container/GRACE_PERIOD"

Topic for Blueprint Container GRACE_PERIOD events

121.17.7.20 public static final String TOPIC_WAITING = "org/osgi/service/blueprint/container/WAITING"

Topic for Blueprint Container WAITING events

121.17.7.21 public static final String TYPE = "type"

The type of the event that has been issued. This property is of type Integer and can take one of the values defined in BlueprintEvent.

121.17.8 public class NoSuchComponentException
extends RuntimeException

A Blueprint exception indicating that a component does not exist in a Blueprint Container. This exception is thrown when an attempt is made to create a component instance or lookup Component Metadata using a component id that does not exist in the Blueprint Container.

121.17.8.1 public NoSuchComponentException(String msg, String id)

The associated message.

The id of the non-existent component.

Create a No Such Component Exception for a non-existent component.

121.17.8.2 public NoSuchComponentException(String id)

The id of the non-existent component.

Create a No Such Component Exception for a non-existent component.

121.17.8.3 public String getComponentId()

Returns the id of the non-existent component.

The id of the non-existent component.

121.17.9 public class ReifiedType

Provides access to a concrete type and its optional generic type parameters.

Java 5 and later support generic types. These types consist of a raw class with type parameters. This class models such a Type class but ensures that the type is reified. Reification means that the Type graph associated with a Java 5 Type instance is traversed until the type becomes a concrete class. This class is available with the getRawClass() method. The optional type parameters are recursively represented as Reified Types.

In Java 1.4, a class has by definition no type parameters. This class implementation provides the Reified Type for Java 1.4 by making the raw class the Java 1.4 class and using a Reified Type based on the Object class for any requested type parameter.

A Blueprint extender implementations can subclass this class and provide access to the generic type parameter graph for conversion. Such a subclass must reify the different Java 5 Type instances into the reified form. That is, a form where the raw Class is available with its optional type parameters as Reified Types.

Immutable

121.17.9.1 public ReifiedType(Class<?> clazz)

The raw class of the Reified Type.

Create a Reified Type for a raw Java class without any generic type parameters. Subclasses can provide the optional generic type parameter information. Without subclassing, this instance has no type parameters.

121.17.9.2 public ReifiedType getActualTypeArgument(int i)

The zero-based index of the requested type parameter.

Return a type parameter for this type. The type parameter refers to a parameter in a generic type declaration given by the zero-based index i. For example, in the following example:

 Map<String, ? extends Metadata>

type parameter 0 is String, and type parameter 1 is Metadata.

This implementation returns a Reified Type that has Object as class. Any object is assignable to Object and therefore no conversion is then necessary. This is compatible with versions of Java language prior to Java 5. This method should be overridden by a subclass that provides access to the generic type parameter information for Java 5 and later.

The ReifiedType for the generic type parameter at the specified index.

121.17.9.3 public Class<?> getRawClass()

Return the raw class represented by this type. The raw class represents the concrete class that is associated with a type declaration. This class could have been deduced from the generics type parameter graph of the declaration. For example, in the following example:

 Map<String, ? extends Metadata>

The raw class is the Map class.

The raw class represented by this type.

121.17.9.4 public int size()

Return the number of type parameters for this type.

This implementation returns 0. This method should be overridden by a subclass that provides access to the generic type parameter information for Java 5 and later.

The number of type parameters for this type.

121.17.10 public class ServiceUnavailableException
extends ServiceException

A Blueprint exception indicating that a service is unavailable. This exception is thrown when an invocation is made on a service reference and a backing service is not available.

121.17.10.1 public ServiceUnavailableException(String message, String filter)

The associated message.

The filter used for the service lookup.

Creates a Service Unavailable Exception with the specified message.

121.17.10.2 public ServiceUnavailableException(String message, String filter, Throwable cause)

The associated message.

The filter used for the service lookup.

The cause of this exception.

Creates a Service Unavailable Exception with the specified message and exception cause.

121.17.10.3 public String getFilter()

Returns the filter expression that a service would have needed to satisfy in order for the invocation to proceed.

The failing filter.

121.18 org.osgi.service.blueprint.reflect

Version 1.0

Blueprint Reflection Package Version 1.0.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.service.blueprint.reflect; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.service.blueprint.reflect; version="[1.0,1.1)"

121.18.1 Summary

121.18.2 public interface BeanArgument

Metadata for a factory method or constructor argument of a bean. The arguments of a bean are obtained from BeanMetadata.getArguments(). This is specified by the argument elements of a bean.

Thread-safe

121.18.2.1 public int getIndex()

Return the zero-based index into the parameter list of the factory method or constructor to be invoked for this argument. This is determined by specifying the index attribute for the bean. If not explicitly set, this will return -1 and the initial ordering is defined by its position in the BeanMetadata.getArguments() list. This is specified by the index attribute.

The zero-based index of the parameter, or -1 if no index is specified.

121.18.2.2 public Metadata getValue()

Return the Metadata for the argument value. This is specified by the value attribute.

The Metadata for the argument value.

121.18.2.3 public String getValueType()

Return the name of the value type to match the argument and convert the value into when invoking the constructor or factory method. This is specified by the type attribute.

The name of the value type to convert the value into, or null if no type is specified.

121.18.3 public interface BeanMetadata
extends Target, ComponentMetadata

Metadata for a Bean component.

This is specified by the bean element.

Thread-safe

121.18.3.1 public static final String SCOPE_PROTOTYPE = "prototype"

The bean has prototype scope.

getScope()

121.18.3.2 public static final String SCOPE_SINGLETON = "singleton"

The bean has singleton scope.

getScope()

121.18.3.3 public List<BeanArgument> getArguments()

Return the arguments for the factory method or constructor of the bean. This is specified by the child argument elements.

An immutable List of BeanArgument objects for the factory method or constructor of the bean. The List is empty if no arguments are specified for the bean.

121.18.3.4 public String getClassName()

Return the name of the class specified for the bean. This is specified by the class attribute of the bean definition.

The name of the class specified for the bean. If no class is specified in the bean definition, because the a factory component is used instead, then this method will return null.

121.18.3.5 public String getDestroyMethod()

Return the name of the destroy method specified for the bean. This is specified by the destroy-method attribute of the bean definition.

The name of the destroy method specified for the bean, or null if no destroy method is specified.

121.18.3.6 public Target getFactoryComponent()

Return the Metadata for the factory component on which to invoke the factory method for the bean. This is specified by the factory-ref attribute of the bean.

When a factory method and factory component have been specified for the bean, this method returns the factory component on which to invoke the factory method for the bean. When no factory component has been specified this method will return null. When a factory method has been specified for the bean but a factory component has not been specified, the factory method must be invoked as a static method on the bean's class.

The Metadata for the factory component on which to invoke the factory method for the bean or null if no factory component is specified.

121.18.3.7 public String getFactoryMethod()

Return the name of the factory method for the bean. This is specified by the factory-method attribute of the bean.

The name of the factory method of the bean or null if no factory method is specified for the bean.

121.18.3.8 public String getInitMethod()

Return the name of the init method specified for the bean. This is specified by the init-method attribute of the bean definition.

The name of the init method specified for the bean, or null if no init method is specified.

121.18.3.9 public List<BeanProperty> getProperties()

Return the properties for the bean. This is specified by the child property elements.

An immutable List of BeanProperty objects, with one entry for each property to be injected in the bean. The List is empty if no property injection is specified for the bean.

121.18.3.10 public String getScope()

Return the scope for the bean.

The scope for the bean. Returns null if the scope has not been explicitly specified in the bean definition.

SCOPE_SINGLETON, SCOPE_PROTOTYPE

121.18.4 public interface BeanProperty

Metadata for a property to be injected into a bean. The properties of a bean are obtained from BeanMetadata.getProperties(). This is specified by the property elements of a bean. Properties are defined according to the Java Beans conventions.

Thread-safe

121.18.4.1 public String getName()

Return the name of the property to be injected. The name follows Java Beans conventions. This is specified by the name attribute.

The name of the property to be injected.

121.18.4.2 public Metadata getValue()

Return the Metadata for the value to be injected into a bean. This is specified by the value attribute or in inlined text.

The Metadata for the value to be injected into a bean.

121.18.5 public interface CollectionMetadata
extends NonNullMetadata

Metadata for a collection based value. Values of the collection are defined by Metadata objects. This Collection Metadata can constrain the values of the collection to a specific type.

Thread-safe

121.18.5.1 public Class<?> getCollectionClass()

Return the type of the collection. The possible types are: array (Object[]), Set, and List. This information is specified in the element name.

The type of the collection. Object[] is returned to indicate an array.

121.18.5.2 public List<Metadata> getValues()

Return Metadata for the values of the collection.

A List of Metadata for the values of the collection.

121.18.5.3 public String getValueType()

Return the type specified for the values of the collection. The value-type attribute specified this information.

The type specified for the values of the collection.

121.18.6 public interface ComponentMetadata
extends NonNullMetadata

Metadata for managed components. This is the base type for BeanMetadata, ServiceMetadata and ServiceReferenceMetadata.

Thread-safe

121.18.6.1 public static final int ACTIVATION_EAGER = 1

The component's manager must eagerly activate the component.

getActivation()

121.18.6.2 public static final int ACTIVATION_LAZY = 2

The component's manager must lazily activate the component.

getActivation()

121.18.6.3 public int getActivation()

Return the activation strategy for the component. This is specified by the activation attribute of a component definition. If this is not set, then the default-activation in the blueprint element is used. If that is also not set, then the activation strategy is ACTIVATION_EAGER.

The activation strategy for the component.

ACTIVATION_EAGER, ACTIVATION_LAZY

121.18.6.4 public List<String> getDependsOn()

Return the ids of any components listed in a depends-on attribute for the component.

An immutable List of component ids that are explicitly declared as a dependency, or an empty List if none.

121.18.6.5 public String getId()

Return the id of the component.

The id of the component. The component id can be null if this is an anonymously defined and/or inlined component.

121.18.7 public interface IdRefMetadata
extends NonNullMetadata

Metadata for the verified id of another component managed by the Blueprint Container. The id itself will be injected, not the component to which the id refers. No implicit dependency is created.

Thread-safe

121.18.7.1 public String getComponentId()

Return the id of the referenced component. This is specified by the component-id attribute of a component.

The id of the referenced component.

121.18.8 public interface MapEntry

Metadata for a map entry. This type is used by MapMetadata, PropsMetadata and ServiceMetadata.

Thread-safe

121.18.8.1 public NonNullMetadata getKey()

Return the Metadata for the key of the map entry. This is specified by the key attribute or element.

The Metadata for the key of the map entry. This must not be null.

121.18.8.2 public Metadata getValue()

Return the Metadata for the value of the map entry. This is specified by the value attribute or element.

The Metadata for the value of the map entry. This must not be null.

121.18.9 public interface MapMetadata
extends NonNullMetadata

Metadata for a Map based value.

This is specified by the map element.

Thread-safe

121.18.9.1 public List<MapEntry> getEntries()

Return the entries for the map.

An immutable List of MapEntry objects for each entry in the map. The List is empty if no entries are specified for the map.

121.18.9.2 public String getKeyType()

Return the name of the type of the map keys. This is specified by the key-type attribute of the map.

The name of the type of the map keys, or null if none is specified.

121.18.9.3 public String getValueType()

Return the name of the type of the map values. This is specified by the value-type attribute of the map.

The name of the type of the map values, or null if none is specified.

121.18.10 public interface Metadata

Top level Metadata type. All Metadata types extends this base type.

Thread-safe

121.18.11 public interface NonNullMetadata
extends Metadata

Metadata for a value that cannot null. All Metadata subtypes extend this type except for NullMetadata.

This Metadata type is used for keys in Maps because they cannot be null.

Thread-safe

121.18.12 public interface NullMetadata
extends Metadata

Metadata for a value specified to be null via the <null> element.

Thread-safe

121.18.12.1 public static final NullMetadata NULL

Singleton instance of NullMetadata.

121.18.13 public interface PropsMetadata
extends NonNullMetadata

Metadata for a java.util.Properties based value.

The MapEntry objects of properties are defined with keys and values of type String.

This is specified by the props element.

Thread-safe

121.18.13.1 public List<MapEntry> getEntries()

Return the entries for the properties.

An immutable List of MapEntry objects for each entry in the properties. The List is empty if no entries are specified for the properties.

121.18.14 public interface ReferenceListener

Metadata for a reference listener interested in the reference bind and unbind events for a service reference.

Thread-safe

121.18.14.1 public String getBindMethod()

Return the name of the bind method. The bind method will be invoked when a matching service is bound to the reference. This is specified by the bind-method attribute of the reference listener.

The name of the bind method.

121.18.14.2 public Target getListenerComponent()

Return the Metadata for the component that will receive bind and unbind events. This is specified by the ref attribute or via an inlined component.

The Metadata for the component that will receive bind and unbind events.

121.18.14.3 public String getUnbindMethod()

Return the name of the unbind method. The unbind method will be invoked when a matching service is unbound from the reference. This is specified by the unbind-method attribute of the reference listener.

The name of the unbind method.

121.18.15 public interface ReferenceListMetadata
extends ServiceReferenceMetadata

Metadata for a list of service references.

This is specified by the reference-list element.

Thread-safe

121.18.15.1 public static final int USE_SERVICE_OBJECT = 1

Reference list values must be proxies to the actual service objects.

getMemberType()

121.18.15.2 public static final int USE_SERVICE_REFERENCE = 2

Reference list values must be ServiceReference objects.

getMemberType()

121.18.15.3 public int getMemberType()

Return whether the List will contain service object proxies or ServiceReference objects. This is specified by the member-type attribute of the reference list.

Whether the List will contain service object proxies or ServiceReference objects.

USE_SERVICE_OBJECT, USE_SERVICE_REFERENCE

121.18.16 public interface ReferenceMetadata
extends Target, ServiceReferenceMetadata

Metadata for a reference that will bind to a single matching service in the service registry.

This is specified by the reference element.

Thread-safe

121.18.16.1 public long getTimeout()

Return the timeout for service invocations when a backing service is unavailable. This is specified by the timeout attribute of the reference.

The timeout, in milliseconds, for service invocations when a backing service is unavailable.

121.18.17 public interface RefMetadata
extends Target, NonNullMetadata

Metadata for a reference to another component managed by the Blueprint Container.

Thread-safe

121.18.17.1 public String getComponentId()

Return the id of the referenced component. This is specified by the component-id attribute of a component.

The id of the referenced component.

121.18.18 public interface RegistrationListener

Metadata for a registration listener interested in service registration and unregistration events for a service.

The registration listener is called with the initial state of the service when the registration listener is actuated.

Thread-safe

121.18.18.1 public Target getListenerComponent()

Return the Metadata for the component that will receive registration and unregistration events. This is specified by the ref attribute or via an inlined component.

The Metadata for the component that will receive registration and unregistration events.

121.18.18.2 public String getRegistrationMethod()

Return the name of the registration method. The registration method will be invoked when the associated service is registered with the service registry. This is specified by the registration-method attribute of the registration listener.

The name of the registration method.

121.18.18.3 public String getUnregistrationMethod()

Return the name of the unregistration method. The unregistration method will be invoked when the associated service is unregistered from the service registry. This is specified by the unregistration-method attribute of the registration listener.

The name of the unregistration method.

121.18.19 public interface ServiceMetadata
extends ComponentMetadata

Metadata for a service to be registered by the Blueprint Container when enabled.

This is specified by the service element.

Thread-safe

121.18.19.1 public static final int AUTO_EXPORT_ALL_CLASSES = 4

Advertise all Java classes and interfaces in the component instance type as service interfaces.

getAutoExport()

121.18.19.2 public static final int AUTO_EXPORT_CLASS_HIERARCHY = 3

Advertise all Java classes in the hierarchy of the component instance type as service interfaces.

getAutoExport()

121.18.19.3 public static final int AUTO_EXPORT_DISABLED = 1

Do not auto-detect types for advertised service interfaces

getAutoExport()

121.18.19.4 public static final int AUTO_EXPORT_INTERFACES = 2

Advertise all Java interfaces implemented by the component instance type as service interfaces.

getAutoExport()

121.18.19.5 public int getAutoExport()

Return the auto-export mode for the service. This is specified by the auto-export attribute of the service.

The auto-export mode for the service.

AUTO_EXPORT_DISABLED, AUTO_EXPORT_INTERFACES, AUTO_EXPORT_CLASS_HIERARCHY, AUTO_EXPORT_ALL_CLASSES

121.18.19.6 public List<String> getInterfaces()

Return the type names of the interfaces that the service should be advertised as supporting. This is specified in the interface attribute or child interfaces element of the service.

An immutable List of String for the type names of the interfaces that the service should be advertised as supporting. The List is empty if using auto-export or no interface names are specified for the service.

121.18.19.7 public int getRanking()

Return the ranking value to use when advertising the service. If the ranking value is zero, the service must be registered without a service.ranking service property. This is specified by the ranking attribute of the service.

The ranking value to use when advertising the service.

121.18.19.8 public Collection<RegistrationListener> getRegistrationListeners()

Return the registration listeners to be notified when the service is registered and unregistered with the framework. This is specified by the registration-listener elements of the service.

An immutable Collection of RegistrationListener objects to be notified when the service is registered and unregistered with the framework. The Collection is empty if no registration listeners are specified for the service.

121.18.19.9 public Target getServiceComponent()

Return the Metadata for the component to be exported as a service. This is specified inline or via the ref attribute of the service.

The Metadata for the component to be exported as a service.

121.18.19.10 public List<MapEntry> getServiceProperties()

Return the user declared properties to be advertised with the service. This is specified by the service-properties element of the service.

An immutable List of MapEntry objects for the user declared properties to be advertised with the service. The List is empty if no service properties are specified for the service.

121.18.20 public interface ServiceReferenceMetadata
extends ComponentMetadata

Metadata for a reference to an OSGi service. This is the base type for ReferenceListMetadata and ReferenceMetadata.

Thread-safe

121.18.20.1 public static final int AVAILABILITY_MANDATORY = 1

A matching service is required at all times.

getAvailability()

121.18.20.2 public static final int AVAILABILITY_OPTIONAL = 2

A matching service is not required to be present.

getAvailability()

121.18.20.3 public int getAvailability()

Return whether or not a matching service is required at all times. This is specified in the availability attribute of the service reference.

Whether or not a matching service is required at all times.

AVAILABILITY_MANDATORY, AVAILABILITY_OPTIONAL

121.18.20.4 public String getComponentName()

Return the value of the component-name attribute of the service reference. This specifies the id of a component that is registered in the service registry. This will create an automatic filter, appended with the filter if set, to select this component based on its automatic id attribute.

The value of the component-name attribute of the service reference or null if the attribute is not specified.

121.18.20.5 public String getFilter()

Return the filter expression that a matching service must match. This is specified by the filter attribute of the service reference.

The filter expression that a matching service must match or null if a filter is not specified.

121.18.20.6 public String getInterface()

Return the name of the interface type that a matching service must support. This is specified in the interface attribute of the service reference.

The name of the interface type that a matching service must support or null when no interface name is specified.

121.18.20.7 public Collection<ReferenceListener> getReferenceListeners()

Return the reference listeners to receive bind and unbind events. This is specified by the reference-listener elements of the service reference.

An immutable Collection of ReferenceListener objects to receive bind and unbind events. The Collection is empty if no reference listeners are specified for the service reference.

121.18.21 public interface Target
extends NonNullMetadata

A common interface for managed components that can be used as a direct target for method calls. These are bean, reference, and ref, where the ref must refer to a bean or reference component.

BeanMetadata, ReferenceMetadata, RefMetadata

Thread-safe

121.18.22 public interface ValueMetadata
extends NonNullMetadata

Metadata for a simple String value that will be type-converted if necessary before injecting.

Thread-safe

121.18.22.1 public String getStringValue()

Return the unconverted string representation of the value. This is specified by the value attribute or text part of the value element.

The unconverted string representation of the value.

121.18.22.2 public String getType()

Return the name of the type to which the value should be converted. This is specified by the type attribute.

The name of the type to which the value should be converted or null if no type is specified.