felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > Apache Felix Application Demonstration
Date Wed, 30 May 2012 18:52:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=FELIX&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Application+Demonstration">Apache
Felix Application Demonstration</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~benediktritter">Benedikt
Ritter</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        Rewrite of major parts of the example<br />
    </div>
        <br/>
                         <h4>Changes (52)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >In order to follow this example you
need three things: <br> <br></td></tr>
            <tr><td class="diff-unchanged" ># a [Subversion|http://subversion.apache.org/]
client to check out the source code
# the IDE of your choice to view the source code <br></td></tr>
            <tr><td class="diff-unchanged" ># [Maven|http://maven.apache.org]
to build the source code <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >!example-application.png|align=center!
<br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2.
Service-Based Application on top of the Framework <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Getting the source code <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Currently,
the service-based example application is only available in our SVN repository. There are four
separate projects that comprise the application, which can be found here: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Currently,
the example application is only available in our source control repositories. We have created
two applications, one for the service and one for the extender-based approach. Both examples
can be run as a bundled application on top of any OSGi implementation or by hosting an embedded
framework. Assuming you are using svn to get the source code, you can find the source at the
following locations: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{noformat} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >http://svn.apache.org/repos/asf/felix/trunk/examples/servicebased.square
<br>http://svn.apache.org/repos/asf/felix/trunk/examples/servicebased.triangle <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
<br>http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.host <br>http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.circle
<br>http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.square <br>http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.triangle
<br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Once
you have the projects checked out you can go into each sub-directory and build it using Maven;
this assumes you have Maven properly installed. To build, simply perform the following in
each project directory: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Building and running the examples <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Once
you have checked out the projects you can go into each sub-directory and build it using Maven;
this assumes you have Maven properly installed. To build, simply perform the following in
each project directory: <br> <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br>mvn clean install
<br>{noformat} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">Once</span>
<span class="diff-added-words"style="background-color: #dfd;">After</span> you
have built the projects, start Felix and then install/start the resulting bundle <span
class="diff-added-words"style="background-color: #dfd;">for one example (service or extender-based)</span>
from the {{target/}} directory of each project directory. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Examine
the source code to understand the details of the approach. In the future this documentation
will hopefully be expanded to described more details. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">To
start the examples using an embedded framework, export the jars you just build to a folder
in your file system. <br>Then start the host.jar and pass the names of all services/extensions
to the application as parameters: <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2.
Service-Based Application embedding the Framework <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{noformat}
<br>java -jar servicebased.host-1.0.0.jar file:/servicebased.circle-1.0.0.jar file:/servicebased.square-1.0.0.jar
file:/servicebased.triangle-1.0.0.jar <br>{noformat} <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
host bundle from the previous section also implements the hosted framework service-based approach.
The host bundle activator has a static {{main()}} method that creates an instance of Felix
and loads the shape service bundles. The shape service implementations are the same for both
the bundled and hosted framework application versions in this case. To execute the hosted
framework application, issue the following command: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">If
you are using an IDE like eclipse, you can run an embedded framework using a custom run configuration.
In eclipse click _Run_ -&gt; _Run Configurations..._ and create a new _Java Application_
run configuration. Select the host project you want to start (servicebased.host or extenderbased.host)
and chose the {{Application}} class as _Main class_ from the org.apache.felix.example.servicebased/extenderbase.host.launch
package. Switch to the _Arguments_ tab and fill in the following _Program arguments_ (assuming
you want to run the extenderbased example): <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{noformat} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">java
-jar target/servicebased.host-1.0.0.jar <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">file:../extenderbased.circle/target/extenderbased.circle-1.0.0.jar
file:../extenderbased.square/target/extenderbased.square-1.0.0.jar file:../extenderbased.triangle/target/extenderbased.triangle-1.0.0.jar
<br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">To
successfully execute the hosted framework version of the application, you must be in the &quot;servicebased.host&quot;
project directory when issuing the above command and you must have already built all of the
other projects (i.e., circle, square, triangle). <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">For
more details on running an application with an embedded framework scroll down to the bottom
of the page. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Examine
the source code to understand the details of the approach. In the future this documentation
will hopefully be expanded to described more details. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Service-Based Application <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2.
Extender-Based Application on top of the Framework <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The
service-based application uses the OSGi service concept and the service registry as the extensibility
mechanism. Therefore the host bundle contains a service interface located at {{org.apache.felix.example.servicebased.host.service.SimpleShape}}.
The SimpleShape service has two properties: a name and an icon. Beside that it defines one
operation: {{draw(Graphics2D g2, Point p)}}. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Currently,
the extender-based example application is only available in our SVN repository. There are
four separate projects that comprise the application, which can be found here: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3.
Defining shapes as services <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Bundles
that want to contribute a shape service have to implement the {{SimpleShape}} interface. Take
a look at the circle bundle for example. The circle bundle only contains one class, the {{Activator}}.
A {{[BundleActivator|http://www.osgi.org/javadoc/r4v43/org/osgi/framework/BundleActivator.html]}}
is responsible for starting up a bundle. Therefore it gets passed in a {{[BundleContext|http://www.osgi.org/javadoc/r4v43/org/osgi/framework/BundleContext.html]}},
that can be used to perform registration of services within the framework. The {{Activator}}
also contains a inner class that implements the {{SimpleShape}} interface and therefore represents
the {{SimpleShape}} implementation of a circle. The {{start(BundleContext context}} method
is used to register the circle implementation as a service: <br> <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.host
<br>http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.circle <br>http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.square
<br>http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.triangle <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Dictionary&lt;String,
Object&gt; dict = new Hashtable&lt;String, Object&gt;(); <br>dict.put(SimpleShape.NAME_PROPERTY,
&quot;Circle&quot;); <br>dict.put(SimpleShape.ICON_PROPERTY, new ImageIcon(this.getClass().getResource(&quot;circle.png&quot;)));
<br>m_context.registerService(SimpleShape.class.getName(), new Circle(), dict); <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Check
out each project using an appropriate SVN command, such as: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">First
a {{[Dictionary|http://docs.oracle.com/javase/6/docs/api/java/util/Dictionary.html]}} is created
to hold the service&#39;s properties. The two service properties are added to the dictionary.
The icon of the circle service is located under src/main/resources/org/apache/example/servicebased/circle/circle.png.
It gets loaded as an {{[ImageIcon|http://docs.oracle.com/javase/6/docs/api/javax/swing/ImageIcon.html]}}
and added as icon property. The service then gets registered in the service registry by passing
the name of the serivce interface, a service object and the service&#39;s properties.
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{noformat}
<br>svn co http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.host <br>{noformat}
<br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3.
Detecting shape services <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Once
you have the projects checked out you can go into each sub-directory and build it using Maven;
this assumes you have Maven properly installed. To build, simply perform the following in
each project directory: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The
host&#39;s {{Activator}} creates a {{DrawingFrame}} for displaying the different shapes.
It then delegates adding and removing of {{SimpleShape}} services to a {{[ServiceTracker|http://www.osgi.org/javadoc/r4v43/org/osgi/util/tracker/ServiceTracker.html]}}
implementation. Then {{ShapeTracker}} gets notified, when a new {{SimpleShape}} service is
added to, modified or removed from the service registry. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Extender-Based Application <br> <br>In contrast to the service-based example,
the extender-based example uses bundles as it&#39;s primary extensibility mechanism. Therefore
the host bundle containts a {{SimpleShape}} interface, that is much like the one from the
service based example. It also containts a {{draw(Graphics2D g2, Point p)}} method and defines
a set of properties. This time the properties are not used as properties for registering a
service, but for defining bundle header properties, that can be read out from a bundles MANIFEST.
<br> <br>h3. Defining shapes as extensions <br> <br>Bundles that want
to contribute a {{SimpleShape}} extension have to implement the {{SimpleShape}} interface.
Have a look at the extender based circle implementation for example. It only contains one
class, {{Circle}}, that implements {{SimpleShape}}. Note, that in contrast to the service-based
example there is no need to define a {{[BundleActivator|http://www.osgi.org/javadoc/r4v43/org/osgi/framework/BundleActivator.html]}}.
This is because, there is no need to register a service within the framework. Information
about the provided shape implementation is located in the bundle headers instead. Have a look
at the circle&#39;s MANIFEST file: <br> <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">mvn
clean install <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Manifest-Version:
1.0 <br>Private-Package: org.apache.felix.example.extenderbased.circle <br>Tool:
Bnd-0.0.238 <br>Bundle-Name: Apache Felix Circle Extension <br>Created-By: Apache
Maven Bundle Plugin <br>Bundle-Vendor: The Apache Software Foundation <br>Build-Jdk:
1.7.0_01 <br>Bundle-Version: 1.0.0 <br>Extension-Class: org.apache.felix.example.extenderbased.circle.Circle
<br>Bnd-LastModified: 1331062969798 <br>Extension-Icon: org/apache/felix/example/extenderbased/circle/circle.p
<br> ng <br>Bundle-ManifestVersion: 2 <br>Bundle-Description: A simple extension
for drawing circles. <br>Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
<br>Bundle-DocURL: http://www.apache.org/ <br>Bundle-SymbolicName: org.apache.felix.example.extenderbased.circle
<br>Import-Package: org.apache.felix.example.extenderbased.host.extension <br>Extension-Name:
Circle <br></td></tr>
            <tr><td class="diff-unchanged" >{noformat} <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Once
you have built the projects, start Felix and then install/start the resulting bundle from
the {{target/}} directory of each project directory. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">As
you can see, the three bundle properties, defined in the {{SimpleShape}} interface are set
as bundle headers. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Examine
the source code to understand the details of the approach. In the future this documentation
will hopefully be expanded to described more details. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Note:
The MANIFEST is generated by the maven build, so you will only find it in the compiled jar.
If you are intrested in automaticly creating MANIFEST files for your bundles, have a look
at the configuration of the [org.apache.felix.maven-bundle-plugin|http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html]
in the pom.xml. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h2.
Extender-Based Application embedding the Framework <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3.
Detecting shape bundles <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The
host bundle from the previous section also implements the hosted framework extender-based
approach. The host bundle activator has a static {{main()}} method that creates an instance
of Felix and loads the shape extension bundles. The shape extension implementations are the
same for both bundled and hosted framework application versions in this case. To execute the
hosted framework application, issue the following command: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Like
the {{[ServiceTracker|http://www.osgi.org/javadoc/r4v43/org/osgi/util/tracker/ServiceTracker.html]}}
for tracking services, there is a {{[BundleTracker|http://www.osgi.org/javadoc/r4v42/org/osgi/util/tracker/BundleTracker.html]}}
for tracking bundles. A {{BundleTracker}} get&#39;s notified, when the state of bundles
it wants to track change. Have a look at {{org.apache.felix.example.extenderbased.host.ShapeBundleTracker}}.
The constructor defines, that only active bundles should be tracked. The {{addingBundle(Bundle
bundle, BundleEvent event)}} method gets called by the framework, when a bundle enters the
state activated. The tracker then checks, if the bundle headers contain the name property
and if so, add the icon to the application. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">{noformat}
<br>java -jar target/extenderbased.host-1.0.0.jar <br>{noformat} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h2.
Embedding the Framework <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">To
successfully execute the hosted framework version of the application, you must be in the &quot;extenderbased.host&quot;
project directory when issuing the above command and you must have already built all of the
other projects (i.e., circle, square, triangle). <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Since
the R4 release the OSGi Framework provides facilities that allow an application to host it&#39;s
own embedded framework instance. Therefore an implementation of the {{[FrameworkFactory|http://www.osgi.org/javadoc/r4v42/org/osgi/framework/launch/FrameworkFactory.html]}}
interface has to be used. OSGi implementors specify their {{FrameworkFactory}} implementation
in the {{META-INF/services/org.osgi.framework.launch.FrameworkFactory}} file. Prior to Java
6, one had to parse the class name in that file by oneself. Luckily Java 6 has the {{[ServiceLoader&lt;S&gt;|http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html]}}
class, that lets you easily instantiate a {{FrameworkFactoy}}. Have a look at the contents
of the {{org.apache.felix.example.extenderbased.host.launch}} package in the extender-based
host bundle (the implementation is the same for the service-based example). <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Examine
the source code to understand the details of the approach. In the future this documentation
will hopefully be expanded to described more details. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The
{{Application}} class is responsible for creating the framework and installing and starting
the bundles. It uses a {{ConfigUtil}} for creating the framework configuration that is needed
to create a framework using the {{FrameworkFactory}}. The {{ConfigUtil}} also creates a temporary
cache directory for the framework. If the creation of the framework is successful, {{installAndStartBundles(String...
bundleLocations)}} will be called to start the actual application. Therefor the {{Activator}}
of the host bundle is instantiated. Note, that the host bundle can not register itself withing
the framework it just created. Only the extension bundles will be registered within the framework.
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">As
you can see no felix specific code is involved in any of the examples. That&#39;s one
of the advantages of OSGi. Bundles that run on Felix will run on every other implementation
of the same OSGi release. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. Feedback <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="ApacheFelixApplicationDemonstration-ApacheFelixApplicationDemonstration"></a>Apache
Felix Application Demonstration</h1>

<p><em>(This document is a work in progress.)</em></p>

<p>Apache Felix provides a foundation for creating modular and dynamically extensible
applications. This page presents an example application to demonstrate the various approaches
to consider when creating a OSGi/Felix-based application.<br/>
It is recommended that you have a look at the more <a href="/confluence/display/FELIX/Getting+Started"
title="Getting Started">basic examples</a> such as <a href="/confluence/display/FELIX/Apache+Felix+Framework+Usage+Documentation"
title="Apache Felix Framework Usage Documentation">Apache Felix Framework Usage Documentation</a>
before you start with this one.</p>

<p>In order to follow this example you need three things:</p>

<ol>
	<li>a <a href="http://subversion.apache.org/" class="external-link" rel="nofollow">Subversion</a>
client to check out the source code</li>
	<li>the IDE of your choice to view the source code</li>
	<li><a href="http://maven.apache.org" class="external-link" rel="nofollow">Maven</a>
to build the source code</li>
</ol>


<p>The source code of the examples is available in the Felix SVN repository at <a
href="http://svn.apache.org/repos/asf/felix/trunk/examples" class="external-link" rel="nofollow">http://svn.apache.org/repos/asf/felix/trunk/examples</a>.
If you feel more familiar with git, you can use the git mirror at: <a href="git://git.apache.org/felix.git"
class="external-link" rel="nofollow">git://git.apache.org/felix.git</a> or browse
the source code at github: <a href="https://github.com/apache/felix" class="external-link"
rel="nofollow">https://github.com/apache/felix</a></p>

<h2><a name="ApacheFelixApplicationDemonstration-PotentialApproaches"></a>Potential
Approaches</h2>

<p>When creating an OSGi-based application there are two main orthogonal issues to consider:</p>

<ol>
	<li>Service model vs. extender model</li>
	<li>Bundled application vs. hosted framework</li>
</ol>


<p>The first issue is actually a general issue when creating OSGi-based applications.
There are two general approaches that can be used when creating an extensible OSGi application.
The service model approach uses the OSGi service concept and the service registry as the extensibility
mechanism. The extender model approach uses the OSGi installed bundle set as the extensibility
mechanism. Both approaches have their advantages and disadvantages and they can be used independently
or together.</p>

<p>The second issue is related to whether your application is run completely on top
of the OSGi framework as a set of bundles or whether your application hosts an embedded OSGi
framework instance. Creating applications completely as a set of bundles is the preferred
approach since it allows the application to run on any OSGi framework, but this it not always
possible. In such cases where it is not possible or desired, then you may host a framework
instance inside your application, which will likely tie your application to that framework
implementation.</p>

<p>The remainder of this document will present variations of an example application
that demonstrates these different approaches.</p>

<h2><a name="ApacheFelixApplicationDemonstration-ExampleApplicationOverview"></a>Example
Application Overview</h2>

<p>The example application is a very simple paint program that effectively functions
identically whether using services/extensions or running embedded/hosted. The application,
called the host, defines a <tt>SimpleShape</tt> service/extension that it uses
to draw shapes. Different implementations of the <tt>SimpleShape</tt> can be created
to allow the application to draw different shapes. Each shape service/extension has name and
icon properties that the application uses for manipulating the services/extensions. Available
shapes are displayed in the application's tool bar. To draw a shape, click on its button in
the tool bar and then click in the drawing canvas. Shapes can be dragged, but not resized.
When new shape services/extensions appear they are automatically added to the tool bar and
they are automatically removed when the shape services/extensions disappear. Closing the application
window causes the framework and the JVM to shut down. The following is a screen shot of the
application.</p>

<p><span class="image-wrap" style="display: block; text-align: center"><img
src="/confluence/download/attachments/61597/example-application.png?version=1&amp;modificationDate=1184334412000"
style="border: 0px solid black" /></span></p>

<h2><a name="ApacheFelixApplicationDemonstration-Gettingthesourcecode"></a>Getting
the source code</h2>

<p>Currently, the example application is only available in our source control repositories.
We have created two applications, one for the service and one for the extender-based approach.
Both examples can be run as a bundled application on top of any OSGi implementation or by
hosting an embedded framework. Assuming you are using svn to get the source code, you can
find the source at the following locations:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>http://svn.apache.org/repos/asf/felix/trunk/examples/servicebased.host
http://svn.apache.org/repos/asf/felix/trunk/examples/servicebased.circle
http://svn.apache.org/repos/asf/felix/trunk/examples/servicebased.square
http://svn.apache.org/repos/asf/felix/trunk/examples/servicebased.triangle

http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.host
http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.circle
http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.square
http://svn.apache.org/repos/asf/felix/trunk/examples/extenderbased.triangle
</pre>
</div></div>

<p>Check out each project using an appropriate SVN command, such as:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>svn co http://svn.apache.org/repos/asf/felix/trunk/examples/servicebased.host
</pre>
</div></div>

<h2><a name="ApacheFelixApplicationDemonstration-Buildingandrunningtheexamples"></a>Building
and running the examples</h2>

<p>Once you have checked out the projects you can go into each sub-directory and build
it using Maven; this assumes you have Maven properly installed. To build, simply perform the
following in each project directory:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>mvn clean install
</pre>
</div></div>

<p>After you have built the projects, start Felix and then install/start the resulting
bundle for one example (service or extender-based) from the <tt>target/</tt> directory
of each project directory.</p>

<p>To start the examples using an embedded framework, export the jars you just build
to a folder in your file system.<br/>
Then start the host.jar and pass the names of all services/extensions to the application as
parameters:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>java -jar servicebased.host-1.0.0.jar file:/servicebased.circle-1.0.0.jar file:/servicebased.square-1.0.0.jar
file:/servicebased.triangle-1.0.0.jar
</pre>
</div></div>

<p>If you are using an IDE like eclipse, you can run an embedded framework using a custom
run configuration. In eclipse click <em>Run</em> -&gt; <em>Run Configurations...</em>
and create a new <em>Java Application</em> run configuration. Select the host
project you want to start (servicebased.host or extenderbased.host) and chose the <tt>Application</tt>
class as <em>Main class</em> from the org.apache.felix.example.servicebased/extenderbase.host.launch
package. Switch to the <em>Arguments</em> tab and fill in the following <em>Program
arguments</em> (assuming you want to run the extenderbased example):</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>file:../extenderbased.circle/target/extenderbased.circle-1.0.0.jar file:../extenderbased.square/target/extenderbased.square-1.0.0.jar
file:../extenderbased.triangle/target/extenderbased.triangle-1.0.0.jar
</pre>
</div></div>

<p>For more details on running an application with an embedded framework scroll down
to the bottom of the page.</p>

<h2><a name="ApacheFelixApplicationDemonstration-ServiceBasedApplication"></a>Service-Based
Application</h2>

<p>The service-based application uses the OSGi service concept and the service registry
as the extensibility mechanism. Therefore the host bundle contains a service interface located
at <tt>org.apache.felix.example.servicebased.host.service.SimpleShape</tt>. The
SimpleShape service has two properties: a name and an icon. Beside that it defines one operation:
<tt>draw(Graphics2D g2, Point p)</tt>.</p>

<h3><a name="ApacheFelixApplicationDemonstration-Definingshapesasservices"></a>Defining
shapes as services</h3>

<p>Bundles that want to contribute a shape service have to implement the <tt>SimpleShape</tt>
interface. Take a look at the circle bundle for example. The circle bundle only contains one
class, the <tt>Activator</tt>. A <tt><a href="http://www.osgi.org/javadoc/r4v43/org/osgi/framework/BundleActivator.html"
class="external-link" rel="nofollow">BundleActivator</a></tt> is responsible
for starting up a bundle. Therefore it gets passed in a <tt><a href="http://www.osgi.org/javadoc/r4v43/org/osgi/framework/BundleContext.html"
class="external-link" rel="nofollow">BundleContext</a></tt>, that can be used
to perform registration of services within the framework. The <tt>Activator</tt>
also contains a inner class that implements the <tt>SimpleShape</tt> interface
and therefore represents the <tt>SimpleShape</tt> implementation of a circle.
The <tt>start(BundleContext context</tt> method is used to register the circle
implementation as a service:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>Dictionary&lt;String, Object&gt; dict = new Hashtable&lt;String, Object&gt;();
dict.put(SimpleShape.NAME_PROPERTY, "Circle");
dict.put(SimpleShape.ICON_PROPERTY, new ImageIcon(this.getClass().getResource("circle.png")));
m_context.registerService(SimpleShape.class.getName(), new Circle(), dict);
</pre>
</div></div>

<p>First a <tt><a href="http://docs.oracle.com/javase/6/docs/api/java/util/Dictionary.html"
class="external-link" rel="nofollow">Dictionary</a></tt> is created to hold
the service's properties. The two service properties are added to the dictionary. The icon
of the circle service is located under src/main/resources/org/apache/example/servicebased/circle/circle.png.
It gets loaded as an <tt><a href="http://docs.oracle.com/javase/6/docs/api/javax/swing/ImageIcon.html"
class="external-link" rel="nofollow">ImageIcon</a></tt> and added as icon property.
The service then gets registered in the service registry by passing the name of the serivce
interface, a service object and the service's properties.</p>

<h3><a name="ApacheFelixApplicationDemonstration-Detectingshapeservices"></a>Detecting
shape services</h3>

<p>The host's <tt>Activator</tt> creates a <tt>DrawingFrame</tt>
for displaying the different shapes. It then delegates adding and removing of <tt>SimpleShape</tt>
services to a <tt><a href="http://www.osgi.org/javadoc/r4v43/org/osgi/util/tracker/ServiceTracker.html"
class="external-link" rel="nofollow">ServiceTracker</a></tt> implementation.
Then <tt>ShapeTracker</tt> gets notified, when a new <tt>SimpleShape</tt>
service is added to, modified or removed from the service registry.</p>

<h2><a name="ApacheFelixApplicationDemonstration-ExtenderBasedApplication"></a>Extender-Based
Application</h2>

<p>In contrast to the service-based example, the extender-based example uses bundles
as it's primary extensibility mechanism. Therefore the host bundle containts a <tt>SimpleShape</tt>
interface, that is much like the one from the service based example. It also containts a <tt>draw(Graphics2D
g2, Point p)</tt> method and defines a set of properties. This time the properties are
not used as properties for registering a service, but for defining bundle header properties,
that can be read out from a bundles MANIFEST.</p>

<h3><a name="ApacheFelixApplicationDemonstration-Definingshapesasextensions"></a>Defining
shapes as extensions</h3>

<p>Bundles that want to contribute a <tt>SimpleShape</tt> extension have
to implement the <tt>SimpleShape</tt> interface. Have a look at the extender based
circle implementation for example. It only contains one class, <tt>Circle</tt>,
that implements <tt>SimpleShape</tt>. Note, that in contrast to the service-based
example there is no need to define a <tt><a href="http://www.osgi.org/javadoc/r4v43/org/osgi/framework/BundleActivator.html"
class="external-link" rel="nofollow">BundleActivator</a></tt>. This is because,
there is no need to register a service within the framework. Information about the provided
shape implementation is located in the bundle headers instead. Have a look at the circle's
MANIFEST file:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>Manifest-Version: 1.0
Private-Package: org.apache.felix.example.extenderbased.circle
Tool: Bnd-0.0.238
Bundle-Name: Apache Felix Circle Extension
Created-By: Apache Maven Bundle Plugin
Bundle-Vendor: The Apache Software Foundation
Build-Jdk: 1.7.0_01
Bundle-Version: 1.0.0
Extension-Class: org.apache.felix.example.extenderbased.circle.Circle
Bnd-LastModified: 1331062969798
Extension-Icon: org/apache/felix/example/extenderbased/circle/circle.p
 ng
Bundle-ManifestVersion: 2
Bundle-Description: A simple extension for drawing circles.
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-DocURL: http://www.apache.org/
Bundle-SymbolicName: org.apache.felix.example.extenderbased.circle
Import-Package: org.apache.felix.example.extenderbased.host.extension
Extension-Name: Circle
</pre>
</div></div>

<p>As you can see, the three bundle properties, defined in the <tt>SimpleShape</tt>
interface are set as bundle headers.</p>

<p>Note: The MANIFEST is generated by the maven build, so you will only find it in the
compiled jar. If you are intrested in automaticly creating MANIFEST files for your bundles,
have a look at the configuration of the <a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"
class="external-link" rel="nofollow">org.apache.felix.maven-bundle-plugin</a> in
the pom.xml.</p>

<h3><a name="ApacheFelixApplicationDemonstration-Detectingshapebundles"></a>Detecting
shape bundles</h3>

<p>Like the <tt><a href="http://www.osgi.org/javadoc/r4v43/org/osgi/util/tracker/ServiceTracker.html"
class="external-link" rel="nofollow">ServiceTracker</a></tt> for tracking services,
there is a <tt><a href="http://www.osgi.org/javadoc/r4v42/org/osgi/util/tracker/BundleTracker.html"
class="external-link" rel="nofollow">BundleTracker</a></tt> for tracking bundles.
A <tt>BundleTracker</tt> get's notified, when the state of bundles it wants to
track change. Have a look at <tt>org.apache.felix.example.extenderbased.host.ShapeBundleTracker</tt>.
The constructor defines, that only active bundles should be tracked. The <tt>addingBundle(Bundle
bundle, BundleEvent event)</tt> method gets called by the framework, when a bundle enters
the state activated. The tracker then checks, if the bundle headers contain the name property
and if so, add the icon to the application.</p>

<h2><a name="ApacheFelixApplicationDemonstration-EmbeddingtheFramework"></a>Embedding
the Framework</h2>

<p>Since the R4 release the OSGi Framework provides facilities that allow an application
to host it's own embedded framework instance. Therefore an implementation of the <tt><a
href="http://www.osgi.org/javadoc/r4v42/org/osgi/framework/launch/FrameworkFactory.html" class="external-link"
rel="nofollow">FrameworkFactory</a></tt> interface has to be used. OSGi implementors
specify their <tt>FrameworkFactory</tt> implementation in the <tt>META-INF/services/org.osgi.framework.launch.FrameworkFactory</tt>
file. Prior to Java 6, one had to parse the class name in that file by oneself. Luckily Java
6 has the <tt><a href="http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html"
class="external-link" rel="nofollow">ServiceLoader&lt;S&gt;</a></tt>
class, that lets you easily instantiate a <tt>FrameworkFactoy</tt>. Have a look
at the contents of the <tt>org.apache.felix.example.extenderbased.host.launch</tt>
package in the extender-based host bundle (the implementation is the same for the service-based
example).</p>

<p>The <tt>Application</tt> class is responsible for creating the framework
and installing and starting the bundles. It uses a <tt>ConfigUtil</tt> for creating
the framework configuration that is needed to create a framework using the <tt>FrameworkFactory</tt>.
The <tt>ConfigUtil</tt> also creates a temporary cache directory for the framework.
If the creation of the framework is successful, <tt>installAndStartBundles(String...
bundleLocations)</tt> will be called to start the actual application. Therefor the <tt>Activator</tt>
of the host bundle is instantiated. Note, that the host bundle can not register itself withing
the framework it just created. Only the extension bundles will be registered within the framework.</p>

<p>As you can see no felix specific code is involved in any of the examples. That's
one of the advantages of OSGi. Bundles that run on Felix will run on every other implementation
of the same OSGi release.</p>

<h2><a name="ApacheFelixApplicationDemonstration-Feedback"></a>Feedback</h2>

<p>Subscribe to the Felix users mailing list by sending a message to <a href="mailto:users-subscribe@felix.apache.org"
class="external-link" rel="nofollow">users-subscribe@felix.apache.org</a>; after
subscribing, email questions or feedback to <a href="mailto:users@felix.apache.org" class="external-link"
rel="nofollow">users@felix.apache.org</a>.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Application+Demonstration">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=61597&revisedVersion=16&originalVersion=15">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Application+Demonstration?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message