Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

First, a composite type is declared inside an iPOJO descriptor. A composite contain always a name attribute, which is the component type name. Inside the <composite></composite>, three instances are declared: the three instances used by our application. Remark that these instances are declared as 'regular' instances. The component attribute indicates the component type to use. Instances can be configured as regular iPOJO instances. Finally, an instance of our type is also declared.
To execute our composition, go in the felix directory and launch the following command:

Code Block
shell
shell
java -jar bin/felix.jar

This version of Felix starts with the iPOJO framework, the iPOJO Arch command and the composite support. So, we just need to install our component types and the composition.
In the Felix prompt, launch the following commands:

Code Block
shell
shell
start file:../spell.services/output/spell.services.jar
start file:../spell.english/output/spell.english.jar
start file:../spell.checker/output/spell.checker.jar
start file:../spell.checker.gui/output/spell.checker.gui.jar

Those commands deploy the component types. Remark that no 'functional' (i.e. neither Check service, nor Dictionary service) services are provided. Deployed bundles provide only iPOJO Factory services:

Code Block
shell
shell
-> services
System Bundle (0) provides:
---------------------------
org.osgi.service.startlevel.StartLevel
org.osgi.service.packageadmin.PackageAdmin
Apache Felix Shell Service (1) provides:
----------------------------------------
...
Apache Felix Bundle Repository (3) provides:
--------------------------------------------
org.osgi.service.obr.RepositoryAdmin
iPOJO (4) provides:
-------------------
...
iPOJO Composite (6) provides:
-----------------------------
...
spell.english (8) provides:
---------------------------
org.apache.felix.ipojo.Factory, org.osgi.service.cm.ManagedServiceFactory
spell.checker (9) provides:
---------------------------
org.apache.felix.ipojo.Factory, org.osgi.service.cm.ManagedServiceFactory
spell.checker.gui (10) provides:
-------------------------------
org.apache.felix.ipojo.Factory, org.osgi.service.cm.ManagedServiceFactory

...

Once deployed and started, the fancy GUI appears:

Now, you can check that the functional services are not unavailable outside the composite:

Code Block
shell
shell
-> services
System Bundle (0) provides:
---------------------------
org.osgi.service.startlevel.StartLevel
org.osgi.service.packageadmin.PackageAdmin
Apache Felix Shell Service (1) provides:
----------------------------------------
...
Apache Felix Bundle Repository (3) provides:
--------------------------------------------
org.osgi.service.obr.RepositoryAdmin
iPOJO (4) provides:
-------------------
...
iPOJO Composite (6) provides:
-----------------------------
...
spell.english (8) provides:
---------------------------
org.apache.felix.ipojo.Factory, org.osgi.service.cm.ManagedServiceFactory
spell.checker (9) provides:
---------------------------
org.apache.felix.ipojo.Factory, org.osgi.service.cm.ManagedServiceFactory
spell.checker.gui (10) provides:
-------------------------------
org.apache.felix.ipojo.Factory, org.osgi.service.cm.ManagedServiceFactory
Bundle 11 provides:
-------------------
org.apache.felix.ipojo.Factory, org.osgi.service.cm.ManagedServiceFactory

Of course, if you stop a bundle providing a required service type, the application is stopped:

Code Block
shell
shell
-> stop 8
-> start 8

Then, the application also supports component type update. However the component type name must not change. We will see later how we can avoid this issue by abstracting implementations.

...

This composite just adds a subservice nested element. This subservice allows importing a service inside the composite. The action attribute specifies that we want to import the service from the parent scope (i.e. superior). The specification attribute indicates the required service.

Now, relaunch Felix and enter another profile name (composition2 for example). Once started, executes the following commands:

Code Block
shell
shell
start file:bundle/org.apache.felix.log-0.9.0-SNAPSHOT.jar
start file:../spell.services/output/spell.services.jar
start file:../spell.english/output/spell.english.jar
start file:../spell.checker-v2/output/spell.checker-v2.jar
start file:../spell.checker.gui/output/spell.checker.gui.jar
start file:../example2/output/composition2.jar

Those commands deploy required component type (note that we deploy spell.checker-v2) and an implementation of the OSGi Log Service. When you execute the last command, the fancy interface re-appears.
Try to enter a wrong word (as composite), and click on the check button. The trace does no more appear... the message is logged inside the log service.
Of course, such composite support dynamism. Try the following scenario

Code Block
shell
shell
stop 9
start 9
stop 7
start 7

...

The previous composition instantiates a dictionary service. This means that the composite looks for an implementation of the Dictionary service and creates an instance of this implementation (i.e. component type) inside the composition.
If several implementations are available, the composite chooses one, and switches to another one if the used implementation becomes unavailable.

To execute this composition, launch Felix and execute the following command:

Code Block
shell
shell
start file:../spell.services/output/spell.services.jar
start file:../spell.english/output/spell.english.jar
start file:../spell.checker/output/spell.checker.jar
start file:../spell.checker.gui/output/spell.checker.gui.jar
start file:../example3/output/composition3.jar

These commands deploy component types and the composition. Only one implementation of the dictionary service is available (English). You can check this by executing the service 8 command.

Code Block
shell
shell
-> services 8
spell.english (8) provides:
---------------------------
component.class = spell.english.EnglishDictionary
component.description = <unknown value type>
component.properties = <unknown value type>
component.providedServiceSpecifications = spell.services.DictionaryService
factory.name = spell.english.EnglishDictionary
factory.state = 1
objectClass = org.apache.felix.ipojo.Factory, 
              org.osgi.service.cm.ManagedServiceFactory
service.id = 39
service.pid = spell.english.EnglishDictionary

Note the component.providedServiceSpecifications property indicating provided services.
Now deploy another implementation of the dictionary service, such as the French dictionary service ☺

Code Block
shell
shell
start file:../spell.french/output/spell.french.jar

Write welcome in the GUI and then check. The word is correctly spelled. Then, stop the bundle providing the English dictionary.

Code Block
shell
shell
stop 8

Write welcome in the GUI, and check. The word is misspelled! Try to write bienvenue and check. The word is correctly spelled. This means that the composite has substitutes the previous English dictionary by the French one. This one will be use until it disappears. If you stop the bundle containing this implementation, the composite becomes invalid.

...

In the previous composition, the composite exports the spell checker service. Moreover, the GUI is also created but in the global context. At runtime, the result will be as following:

The composite published the spell checker service in the OSGi service registry. The GUI tracks this service in the OSGi service registry too.
To execute this composition, launch Felix and execute following the commands:

Code Block
shell
shell
start file:../spell.services/output/spell.services.jar
start file:../spell.english/output/spell.english.jar
start file:../spell.checker/output/spell.checker.jar
start file:../spell.checker.gui/output/spell.checker.gui.jar
start file:../example4/output/composition4.jar

You can check that the composition exports the service with the following command:

Code Block
shell
shell
-> services 11
Bundle 11 provides:
-------------------
component.description = <unknown value type>
component.properties = <unknown value type>
component.providedServiceSpecifications = spell.services.SpellChecker
factory.name = composition4
factory.state = 1
objectClass = org.apache.felix.ipojo.Factory, 
              org.osgi.service.cm.ManagedServiceFactory
service.id = 36
service.pid = composition4
----
factory.name = composition4
instance.name = composition4-0
objectClass = spell.services.SpellChecker
service.id = 37

So, now you can play with dynamism. Stop the bundle containing the Check service implementation. The GUI disappears. Restart it. The GUI reappears. Now, stop the bundle containing the GUI implementation. The checker service stills available. Indeed, the GUI is no more inside the composition, and so stills valid despite the unavailability of the GUI:

Code Block
shell
shell
-> stop 8
-> start 8
-> stop 10
-> services 11
Bundle 11 provides:
-------------------
component.description = <unknown value type>
component.properties = <unknown value type>
component.providedServiceSpecifications = spell.services.SpellChecker
factory.name = composition4
factory.state = 1
objectClass = org.apache.felix.ipojo.Factory, 
              org.osgi.service.cm.ManagedServiceFactory
service.id = 36
service.pid = composition4
----
factory.name = composition4
instance.name = composition4-0
objectClass = spell.services.SpellChecker
service.id = 41
-> 

...

The composition5 contains an instance of the composition4 and of the GUI. So the spell checker service exported by the composition4 is published inside the service context of the composite 5 (the parent context). The GUI instance lives in this service context, and so can access to the exported Spell checker service.

To execute this composition, restart Felix and launch the following commands:

Code Block
shell
shell
start file:../spell.services/output/spell.services.jar
start file:../spell.english/output/spell.english.jar
start file:../spell.checker/output/spell.checker.jar
start file:../spell.checker.gui/output/spell.checker.gui.jar
start file:../example5/output/composition5.jar

...