<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gridshore &#187; OSGi</title>
	<atom:link href="http://www.gridshore.nl/tag/osgi/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gridshore.nl</link>
	<description>A weblog about software engineering, Architecture, Technology an other things we like.</description>
	<lastBuildDate>Tue, 13 Dec 2011 15:36:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Book review: OSGi and Apache Felix 3.0</title>
		<link>http://www.gridshore.nl/2011/01/05/book-review-osgi-and-apache-felix-3-0/</link>
		<comments>http://www.gridshore.nl/2011/01/05/book-review-osgi-and-apache-felix-3-0/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 08:59:10 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[bookreview]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1130</guid>
		<description><![CDATA[<p>At the end of 2010 I reviewed the book “OSGi and Apache Felix 3.0 Beginner’s Guide“. The people from packt publishing contacted me based on my involvement in the past with OSGi and felix. I wrote a number of blog posts on OSGi and felix and gave a presentation at the NLJug together with [...]]]></description>
			<content:encoded><![CDATA[<p>At the end of 2010 I reviewed the book “OSGi and Apache Felix 3.0 Beginner’s Guide“. The people from packt publishing contacted me based on my involvement in the past with OSGi and felix. I wrote a number of blog posts on OSGi and felix and gave a presentation at the NLJug together with Allard about the topic. During the process of reviewing, I got enthusiastic about the book. I think the result is a good book for people that want to learn about OSGi by getting their hands dirty.</p>
<p>You can find the complete book review on this page: <a href="http://www.gridshore.nl/book-reviews/osgi-and-apache-felix-3-0-beginners-guide/">OSGi and Apache Felix 3.0 Beginner’s Guide</a></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2011%2F01%2F05%2Fbook-review-osgi-and-apache-felix-3-0%2F&amp;title=Book%20review%3A%20OSGi%20and%20Apache%20Felix%203.0&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2011/01/05/book-review-osgi-and-apache-felix-3-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Spring DM server compliant OSGi bundles with Maven</title>
		<link>http://www.gridshore.nl/2009/01/03/building-spring-dm-server-compliant-osgi-bundles-with-maven/</link>
		<comments>http://www.gridshore.nl/2009/01/03/building-spring-dm-server-compliant-osgi-bundles-with-maven/#comments</comments>
		<pubDate>Sat, 03 Jan 2009 11:54:36 +0000</pubDate>
		<dc:creator>Allard</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[Spring Dynamic Modules]]></category>
		<category><![CDATA[spring framework]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=594</guid>
		<description><![CDATA[<p> <p>Recently, SpringSource released the first version of their DM server. The SpringSource DM Server provides the ability to build enterprise web applications. In the basis, S2DM is a fine mixture of Equinox and Tomcat.</p> <p>Building OSGi-based web applications was already possible, but it is tedious and error prone work. The typical hello-world example [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/s2-logo.png" alt="s2-logo" title="s2-logo" width="213" height="66" class="alignleft size-full wp-image-605" />
<p>Recently, SpringSource released the first version of their DM server. The SpringSource DM Server provides the ability to build enterprise web applications. In the basis, S2DM is a fine mixture of Equinox and Tomcat.</p>
<p>Building OSGi-based web applications was already possible, but it is tedious and error prone work. The typical hello-world example was easy to get going, but as soon as Hibernate or any other framework that helps in larger applications show up, so do your good old class loading problems. For classes to be visible in OSGi, a bundle must declare an Import-Package entry in the Manifest file. Chances are small that Hibernate (even if it were packaged as an OSGi bundle) has these entries for your persistent classes. This is where S2DM server comes in. It allows the more-than-hello-world web applications to be deployed in an environment where you can benefit from the best of OSGi, without the class loading misery. To do this, they have included some extra Manifest entries that are translated to OSGi-compliant directives at load time.</p>
<p>Comparable to the WAR, or better, EAR file, S2DM server supports the PAR file. A PAR file is much like a Jar, with some special headers in the Manifest file, containing all your bundle jars. Some of these jars may contain web bundles, while other typically contain domain classes or the service layer implementation. Contrary to EAR files, a PAR should only contain your own code. It is best practice to deploy frameworks and third party libraries separately. I&#8217;ll explain why later on.</p>
<p>With enterprise applications come enterprise development processes, using continuous integration, build servers and maven. In this post, I&#8217;ll lay out what you need to get maven to build S2DM server compliant bundles, and better, PAR files.</p>
<p><span id="more-594"></span></p>
<p><strong>OSGi manifest headers</strong></p>
<p>But before we move straight to maven, let&#8217;s have a look at what a Spring DM bundle looks like. Basically, a Spring DM bundle is an ordinary OSGi bundle. It has the same requirements for the MANIFEST.MF file, of which the major headers are listed below:</p>
<ul>
<li>
<div><code>Bundle-SymbolicName</code> is the only mandatory manifest header. It represents the technical name of your bundle. This value, in combination with the Bundle-Version, if present, must be unique.</div>
</li>
<li>
<div><code>Bundle-Version</code> is not mandatory, but defaults to 0.0.0, which isn&#8217;t a meaningful version. An OSGi compatible version number has the format: &lt;<em>major</em>&gt;.&lt;<em>minor</em>&gt;.&lt;<em>micro</em>&gt;-&lt;<em>classifier</em>&gt;.</div>
</li>
<li>
<div>The <code>Import-Package</code> header allows you to specify a list of packages that your bundle requires to operate. It is also possible to specify version ranges and that some packages are optional.</div>
</li>
<li>
<div><code>DynamicImport-Package</code> can be used to dynamically import packages at the moment they are required. Use a wildcard (*) to set package patterns to limit the dynamic import to.</div>
</li>
<li>
<div>The last entry I&#8217;ll mention here is <code>Export-Package</code>. It specifies the packages of the current bundle that form its API. Classes in these packages are available for other bundles to use.</div>
</li>
</ul>
<p>For more details about OSGi manifest headers, see the <a title="OSGi R4.1 specification download page" href="http://www.osgi.org/Download.Release4V41" target="_blank">OSGi-core specification</a>, section 3.2.</p>
<p>The OSGi specification requires you to import a package (which has to be exported by another bundle) for a class loader to find it. This lead to problems when using frameworks such as Hibernate, which has to instantiate classes from your application. There is no way a Hibernate OSGi bundle can know beforehand which classes it will instantiate. Another problem is that the number of packages you will have to import is probably very large. Frameworks sometimes offer large amounts of classes that have been grouped into numerous packages. To mention each of those packages in your <code>Import-Package</code> manifest header is a lot of work. You could use the <code>DynamicImport-Package</code> to import all packages you require, but that will create as many problems as it solves. OSGi is designed to only resolve bundles when all requirements have been met. By dynamically importing packages, the OSGi framework has no way to know whether requirements are met, and will resolve your bundle. During runtime, you could get class loader exceptions.</p>
<p><strong>Spring DM specific manifest headers</strong></p>
<p>To counter both the large number of imports and the class loading problems, Spring DM introduced some additional manifest headers. Not that these are not (yet) official OSGi compatible headers and are only evaluated by Spring DM compatible OSGi environments, such as <a href="http://www.springsource.com/products/suite/dmserver">Spring DM Server</a>, for which there is a community and an enterprise version.</p>
<p>The most important additional Spring DM manifest headers for bundles are:</p>
<ul>
<li>
<div><code>Import-Library</code> can be used to import a library. A library is a specification of a set of bundles that should be imported as a whole. Examples of libraries are Hibernate and the Spring Framework.</div>
</li>
<li>
<div><code>Import-Bundle</code> is used to import all the packages from a specific bundle, such as Spring-Core. Typically, this header is used in library specifications, but it may also be used in bundles manifests.</div>
</li>
<li>
<div><code>Module-Type</code> specifies the type of this bundle. At the time of writing, only &#8220;Web&#8221; is supported. When adding this header to the manifest, you indicate that this bundle is to be treated as a Web Module.</div>
</li>
<li>
<div><code>Web-context path</code> specifies the URL in which a Web Module must be deployed. It default to the module&#8217;s file name minus the extension.</div>
</li>
<li>
<div><code>Web-FilterMappings</code> is used to specify the filter names (that reference spring bean names) and their URL mappings</div>
</li>
<li>
<div><code>Web-DispatcherServletUrlPatterns</code> indicates the URLs that have to be mapped to the DispatcherServlet. In Spring DM, a dispatcher servlet is automatically initialized with the context files in <code>META-INF/spring/*.xml.</code></div>
</li>
</ul>
<p><strong>Creating an OSGi bundle with maven</strong></p>
<p>Now that we know which headers have to be generated, lets move on to maven to find how we can generate a manifest file for them. Obviously, you could generate one yourself. This is, however, tedious and error prone. It is best to conform yourself to some design standards, such as using <code>.internal</code> or <code>.impl</code> packages to store classes that are not part of your public API. When you do so, the maven-bundle-plugin.</p>
<p>The maven-bundle-plugin is used to generate an OSGi bundle from your module. In order to make it work, you have to make a few modifications to an otherwise normal <em>pom.xml</em>file:</p>
<ol>
<li>
<div>The &lt;packaging&gt; element value must be set to bundle: <code>&lt;packaging&gt;bundle&lt;packaging&gt;</code></div>
</li>
<li>
<div>Configure the org.apache.felix:maven-bundle-plugin</div>
</li>
</ol>
<p>
<pre class="brush: xml; title: ; notranslate">
&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.apache.felix&lt;/groupId&gt;
            &lt;artifactId&gt;maven-bundle-plugin&lt;/artifactId&gt;
            &lt;extensions&gt;true&lt;/extensions&gt;
            &lt;configuration&gt;
                &lt;instructions&gt;
                    ...
                &lt;/instructions&gt;
            &lt;/configuration&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;
</pre>
</p>
<p>This configuration will generate OSGi compliant manifest files. The <code>Bundle-SymbolicName</code> will be formed from your modules groupId and artifactId and the <code>Bundle-Version</code> will be set to you module&#8217;s version. By default, all packages that are mentioned in your source code&#8217;s import statements will be imported by your bundle, even if these packages are also included in your bundle (see this <a href="http://www.osgi.org/blog/2007/04/importance-of-exporting-nd-importing.html" target="_blank">post</a> on the OSGi Alliance website). Furthermore, all packages available in your bundle will be exported, even the <code>.impl</code> and <code>.internal</code> packages.</p>
<blockquote><p><code>Manifest-Version: 1.0<br />
Export-Package: springdm.domain;uses:="javax.persistence",springdm.per<br />
&nbsp;sistence.impl;uses:="springdm.domain,org.springframework.transaction.<br />
&nbsp;annotation,springdm.persistence,javax.persistence,org.springframework<br />
&nbsp;.beans.factory",springdm.persistence;uses:="springdm.domain"<br />
Private-Package: springdm.*.impl.*<br />
Built-By: allard<br />
Tool: Bnd-0.0.255<br />
Bundle-Name: Spring DM Persistence<br />
Import-Library: org.hibernate.ejb;version="[3.3.2.GA,3.3.2.GA]"<br />
Created-By: Apache Maven Bundle Plugin<br />
Import-Bundle: org.springframework.orm;version="[2.5.6.A,2.5.6.A]"<br />
DynamicImport-Package: *<br />
Build-Jdk: 1.6.0_06<br />
Bundle-Version: 1.0.0.SNAPSHOT<br />
Bnd-LastModified: 1230983705375<br />
Bundle-ManifestVersion: 2<br />
Bundle-SymbolicName: springdm.persistence<br />
Import-Package: com.mysql.jdbc.jdbc2.optional,javax.persistence,javax.<br />
&nbsp;sql,org.hibernate.jdbc,org.springframework.beans.factory,org.springfr<br />
&nbsp;amework.transaction.annotation,springdm.domain,springdm.persistence,s<br />
&nbsp;pringdm.persistence.impl<br />
</code></p></blockquote>
<p>I am not going into more detail about how to configure the bundle plugin to keep implementation packages private. See the felix <a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html" target="_blank">documentation</a> for more information about that.</p>
<p><strong>Adding Spring DM manifest headers</strong></p>
<p>Well, that actually quite easy. All you have to do is specify the name of the header as a sub element in the <code>&lt;instructions&gt;</code> element and the value of the header as the value of that element, for example: </p>
<blockquote><p><code>&lt;Import-Bundle&gt;org.springframework.orm;version="[2.5.6.A,2.5.6.A]"&lt;/Import-Bundle&gt;</code></p></blockquote>
<p>The problem is to find out which bundles or libraries there are to import, and which versions they have. That&#8217;s why Spring started the <a href="http://www.springsource.com/repository/app/" target="_blank">Spring DM bundle repository</a>. You can use it to find libraries and OSGi bundles for most commonly used frameworks. For each of thus libraries or bundles, it will tell you which maven dependency to use (for compilation) and which manifest entry has to be added to your bundle. Make sure that your maven dependencies and manifest entries are updated, otherwise you could run into problems at runtime.</p>
<p>For maven to find the artifacts in the bundle repository, you have to configure some repositories. You can find them <a href="http://www.springsource.com/repository/app/faq#q8" target="_blank">here</a>.</p>
<p>If your bundle is a Web Bundle, add the required <code>&lt;Module-Type&gt;Web&lt;/Module-Type&gt;</code> element to the instructions, as well as any other required Web-* headers.</p>
<p>That&#8217;s actually it. That&#8217;s all it takes to generate Spring DM specific manifest entries.</p>
<p><strong>Creating a PAR deployment unit</strong></p>
<p>The PAR file is the deployment unit for Spring DM applications. It is a Jar file with special manifest headers that contains all application specific bundles. You should never include framework bundles in the par file. In conventional environments, class loaders would prevent you from having different versions of the same class on your class path. Therefore, you had to add frameworks to the WAR file, to prevent version conflicts with other applications. In OSGi, there is no problem with having the same class multiple times. You just specify a version restriction in your import headers and OSGi takes care of the resolution process. To keep PAR files small, you can deploy required libraries and bundles in the /repository/libraries/usr and /repository/bundles/usr folders respectively. Any application can reuse any existing framework bundles.</p>
<p>The PAR file has another advantage. Spring DM Server prevents bundles from outside the PAR file from accessing bundles inside the PAR file. This way, you can deploy applications without running the risk of classes and services intermingling.</p>
<p>Now, let&#8217;s get back to maven to create ourselves a par file. First, create a new module in your maven project. This module&#8217;s pom file should have <code>&lt;packaging&gt;</code> set to <code>par</code>. Next, add dependencies to each module you want to be included in the par file. The par plugin does not include transitive dependencies, since framework bundles should not be included. Finally, add the maven-par-plugin to your plugin configuration.</p>
<p>
<pre class="brush: xml; title: ; notranslate">
&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
            &lt;artifactId&gt;maven-par-plugin&lt;/artifactId&gt;
            &lt;version&gt;0.2.0&lt;/version&gt;
            &lt;extensions&gt;true&lt;/extensions&gt;
            &lt;configuration&gt;
                &lt;fqn&gt;true&lt;/fqn&gt;
                &lt;applicationSymbolicName&gt;gridshore.samples.springdm&lt;/applicationSymbolicName&gt;
                &lt;applicationVersion&gt;1.0.0&lt;/applicationVersion&gt;
                &lt;applicationDescription&gt;Gridshore Spring DM sample&lt;/applicationDescription&gt;
                &lt;applicationName&gt;Gridshore Spring DM sample&lt;/applicationName&gt;
            &lt;/configuration&gt;
            &lt;executions&gt;
                &lt;execution&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;par&lt;/goal&gt;
                    &lt;/goals&gt;
                    &lt;phase&gt;package&lt;/phase&gt;
                &lt;/execution&gt;
            &lt;/executions&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;
</pre>
</p>
<p>You probably need to configure a repository to find this plugin: <a href="http://repo.steademy.com/beta/maven2">http://repo.steademy.com/beta/maven2</a>. You can find documentation of the maven-par-plugin <a href="http://blog.steademy.com/2008/05/29/maven-par-plugin/" target="_blank">here</a>.</p>
<p>Now run <code>mvn install</code> and see your PAR being created for you. Since your PAR does not contain framework bundles, you have to install them separately. To make sure that all dependencies are available, you can use the maven-assembly-plugin to create a zip file with the PAR file as well as all the framework bundles you require.</p>
<p>Have fun!</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F01%2F03%2Fbuilding-spring-dm-server-compliant-osgi-bundles-with-maven%2F&amp;title=Building%20Spring%20DM%20server%20compliant%20OSGi%20bundles%20with%20Maven&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/01/03/building-spring-dm-server-compliant-osgi-bundles-with-maven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Service orientation within applications</title>
		<link>http://www.gridshore.nl/2008/03/21/service-orientation-within-applications/</link>
		<comments>http://www.gridshore.nl/2008/03/21/service-orientation-within-applications/#comments</comments>
		<pubDate>Fri, 21 Mar 2008 19:45:14 +0000</pubDate>
		<dc:creator>Allard</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2008/03/21/service-orientation-within-applications/</guid>
		<description><![CDATA[<p>Many IT projects at large companies aim to make the company &#8220;SOA-proof&#8221;. What really concerns me is that time after time software architects tend to treat &#8220;XML Web Services&#8221; as a synonym for &#8220;Service&#8221;. In this article, I want to show that SOA may also exist within a single application.</p> <p></p> <p>Often, a perfectly [...]]]></description>
			<content:encoded><![CDATA[<p>Many IT projects at large companies aim to make the company &#8220;SOA-proof&#8221;. What really concerns me is that time after time software architects tend to treat &#8220;XML Web Services&#8221; as a synonym for &#8220;Service&#8221;. In this article, I want to show that SOA may also exist within a single application.</p>
<p><span id="more-77"></span></p>
<p>Often, a perfectly homogenous application is split up in several components that have a great deal of interaction and even share a common domain model. The general idea behind this separation in components is reuse. However, the intended reuse is often not achieved, as other applications often tend to have just a slightly different need.</p>
<p>Furthermore, separation of an application into XML Web Service components comes at a very large price. Precious processing time is lost in (un)marshalling object trees to XML and back. A common way of reasoning is that adding a few more servers or caching requests and responses would solve the problem. Neither of these solutions, however, is quite elegant and should be kept as a last resort.</p>
<p>There is a more elegant solution to achieve loose coupling between components, without the (un)marshalling loss, while still maintaining the possibility to provide your &#8220;services&#8221; to any other external component. This solution is OSGi.</p>
<p>I will not get into too much detail about OSGi in this article, as there are many articles to be found about that, but here are some key features of  OSGi:</p>
<ul>
<li>The OSGi specification is defined by the OSGi Alliance [<a href="http://www.osgi.org" title="OSGi Alliance Website" target="_blank">www.osgi.org</a>];</li>
<li>A bundle (the OSGi application building block) is a black box for other bundles, except for the resources that have been explicitly exposed;</li>
<li>OSGi bundles can be installed, started, stopped and uninstalled at runtime;</li>
<li>Each bundle, when started, can provide one or more services. These services may come and go at runtime;</li>
<li>Bundles can use services without knowledge of their implementation. They can contain metadata that may be used to search a specific service;</li>
<li>Bundles are versioned. Multiple bundles may provide different versions of the same resources. The OSGi framework will resolve the dependencies perfectly;</li>
<li>An OSGi application runs completely inside the same JVM, making it very fast (comparing to Web Services or JMS).</li>
</ul>
<p>The strict visibility rules of the OSGi framework ensure that the loose coupling between components is maintained at all times. OSGi&#8217;s advanced class loading allows for several versions of the same bundle to be active at the same time. This makes it quite easy to make modifications in an application, while maintaining backwards compatibility. In fact, OSGi allows for an easy solution of the <a href="http://www.nljug.org/pages/events/content/jspring_2007/sessions/00003/" title="Web Service versioning with OSGi at JSpring 2007" target="_blank">Web Service Versioning dilemma</a>.</p>
<p>OSGi bundles run inside a single JVM, meaning that OSGi services are not exposed to external applications. However, since an OSGi service just provides an interface to an external user, it is easy to create another bundle that provides this OSGi service (when available) to the outside world as a Web Service. Or maybe as a JMS service. Or one for each. This means that we don&#8217;t loose processing time on unnecessary marshalling, but still keep the possibility to simply expose any service to the outside world, if the need comes along (and not by default as is the case with an XML WS).</p>
<p>To recap, besides just being a technologically interesting framework, OSGi offers interesting capabilities to be used in a SOA environment. One of these capabilities is the separation of an application in components that provide each other services. Although these services are not available outside the OSGi context, it is easy to create a bundle that exposes these OSGi services as e.g. Web Services or via JMS.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F03%2F21%2Fservice-orientation-within-applications%2F&amp;title=Service%20orientation%20within%20applications&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/03/21/service-orientation-within-applications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a jetty based OSGi HttpService for apache felix</title>
		<link>http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/</link>
		<comments>http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/#comments</comments>
		<pubDate>Fri, 29 Feb 2008 21:02:08 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/</guid>
		<description><![CDATA[<p>OSGi has a service spec called http.service (see Service Compendium document of the OSGi Alliance). Felix has an implementation for it that is based around jetty 4.x. Since we are at jetty 6.1.7 at the moment I thought about trying to create an implementation of my own. Not that it is really necessary, you [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/logo1.png" alt="logo.png" border="0" width="165" height="63" align="left" />OSGi has a service spec called http.service (see Service Compendium document of the OSGi Alliance). Felix has an implementation for it that is based around jetty 4.x. Since we are at jetty 6.1.7 at the moment I thought about trying to create an implementation of my own. Not that it is really necessary, you can expose resources without complying to the spec (<a href="http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/">see my other post</a>).</p>
<p> But the spec is there for a reason, so let&#8217;s try to adhere to it first. The specification is up to the following two interfaces and one exception.</p>
<ul>
<li>HttpContext &#8211; Enables bundles to use provided information about a servlet or resource during registration.</li>
<li>HttpService &#8211; Enables other bundles to dynamically register sevlets or resources into the Http Service URI namespace.</li>
<li>NamespaceException &#8211; Thrown when a problem arises during registration of a servlet or resource into the Http Service UIR namespace.</li>
</ul>
<p>At first I tried to create my own implementation for these interfaces. It did not look to hard, but in the end I found the following patch which made my life a lot easier.<br /><a href="https://issues.apache.org/jira/secure/attachment/12372787/FELIX-55_jetty6.patch">jetty6 patch</a></p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/jetty-logo.gif" alt="jetty_logo.gif" border="0" width="269" height="112" align="right" />To be able to understand the implementation of an Http Service using jetty, you should understand the basics with respect to Jetty. In a forthcoming post I&#8217;ll talk more about these details. Within this post I&#8217;ll concentrate on the using of the service. I do need to make a few remarks. What if you do not want to apply the patch, change the pom, etc. Well you can download the one I have created from here : <a href="http://code.google.com/p/gridshore/source/browse/trunk/FelixTryout/RunnerApp/bundle/org.apache.felix.http.jetty-0.9.0-GRIDSHORE.jar">org.apache.felix.http.jetty-0.9.0-GRIDSHORE.jar</a>. Another thing I would like to stress is the current state of the bundle. There are a lot of TODO&#8217;d in there. It looks like security is not implemented as it should. There is a completely different implementation at the <a href="http://wiki.ops4j.org/confluence/display/ops4j/Pax+Web">ops4j website</a>. One disadvantage is the level of control, need to look into that thing again. It is much more complicated, uses other bundles of the pax project. It does look interesting, but for me it is not easy enough. Another implementation is available at the <a href="http://incubator.apache.org/sling/site/index.html">sling website</a>. But again a lot to graps before you can start. So for now I have chosen to continue with the slightly limited implementation, adhere to the spec and my bundles should work with the others as well.</p>
<p>Read more to learn about the sample using http.service and maven to build the bundle.</p>
<p><span id="more-66"></span></p>
<h2>The sample</h2>
<p>The goal was to play around with servlets and resources. I want to get a better idea about what OSGi can do. So I used the runner I introduced in my previous post (<a href="http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/">starting-with-osgi-using-apache-felix-step-1</a>). Of course there are some other bundles and there is an extra property to configure the jetty intance:</p>
<pre>
<strong>configMap.put("org.osgi.service.http.port","9081"); // set the port to listen to for jetty</strong>
configMap.put(AutoActivator.AUTO_START_PROP + ".1",
    "file:" + BUNDLE_ROOT + "training-service/1.0-SNAPSHOT/training-service-1.0-SNAPSHOT.jar " +
    "file:" + BUNDLE_ROOT + "http-servlets/1.0-SNAPSHOT/http-servlets-1.0-SNAPSHOT.jar " +
    "file:" + JETTY_ROOT + "jetty/6.1.7/jetty-6.1.7.jar " +
    "file:" + JETTY_ROOT + "jetty-util/6.1.7/jetty-util-6.1.7.jar " +
    "file:" + JETTY_ROOT + "servlet-api-2.5/6.1.7/servlet-api-2.5-6.1.7.jar " +
    "file:bundle/org.osgi.compendium-1.0.0.jar " +
    "file:bundle/slf4j-api-1.4.3.jar " +
    "file:bundle/slf4j-simple-1.4.3.jar " +
<strong>    "file:bundle/org.apache.felix.http.jetty-0.9.0-GRIDSHORE.jar " + // use the created patched http.service</strong>
    "file:bundle/org.apache.felix.shell-1.0.0.jar " +
    "file:bundle/org.apache.felix.shell.tui-1.0.0.jar ");
</pre>
<p>The training service is a very easy service with one method returning a list of trainings. The more interesting bundle is the http-servlets bundle. This bundle contains the servlet that uses the training-service and some static resources like html pages, style sheets, etc. Let&#8217;s start with a look at the internal structure of the bundle. Please remember that we use the <a href="http://cwiki.apache.org/FELIX/bundle-plugin-for-maven-bnd.html">maven-bundle-plugin</a> plugin. Therefore we adhere to basic maven project structure. The java files are in the src/main/java folder. The static resources are in the src/main/resources folder. The plugin than creates the right MANIFEST.MF file.</p>
<pre>
Manifest-Version: 1.0
Built-By: jettro
Created-By: Apache Maven Bundle Plugin
Bundle-Activator: nl.gridshore.samples.bundles.httpservlets.impl.Activ
 ator
Import-Package: javax.servlet;version="2.5",javax.servlet.http;version
 ="2.5",nl.gridshore.samples.bundles.trainingservice.api,org.osgi.fram
 ework;version="1.3",org.osgi.service.http;version="1.2",org.slf4j;ver
 sion="1.4"
Bnd-LastModified: 1204315796232
Bundle-Version: 1.0.0.SNAPSHOT
Bundle-Name: http-servlets
Build-Jdk: 1.5.0_13
<strong>Private-Package: htmls,htmls.css,htmls.images,nl.gridshore.samples.bun
 dles.httpservlets.impl</strong>
Bundle-ManifestVersion: 2
Bundle-SymbolicName: http-servlets
Tool: Bnd-0.0.227
</pre>
<p>Take good notice of the Private-Packge, here the directories are listed that are in the resources folder. So by default these resources are private. We need the http service to expose these resources. The next step is to have a look at the Activator of the http-servlets bundle. Let&#8217;s step through the separate methods that are important.</p>
<pre>
<strong>public void start(BundleContext bundleContext) throws Exception</strong> {
    this.bundleContext = bundleContext;
    doRegister();
    synchronized (this) {
        bundleContext.addServiceListener(this,
                "(|(objectClass=" + TrainingService.class.getName() + ")" +
                "(objectClass=" + HttpService.class.getName() + "))");
    }
}
</pre>
<p>Two important things happen in the start method, we first try to register the servlet (more on that later). After that we add a service listener that listens to events related to the TrainingService class and the HttpService class. This means that if one of these instances are started, stopped or updated we are notified. This notification is important to unregister the servlet if the training service disappears. Of course it is also important to register the servlet if the http service becomes available. Let&#8217;s move on to the register methods.</p>
<pre>
<strong>private void register() throws InvalidSyntaxException, ServletException, NamespaceException</strong> {
    ServiceReference[] trainingReferences = bundleContext.getServiceReferences(TrainingService.class.getName(), null);
    TrainingService trainingService = null;
    if (trainingReferences != null) {
        trainingService = (TrainingService) bundleContext.getService(trainingReferences[0]);
    } else {
        logger.info("No training service available");
    }

    ServiceReference[] httpReferences = bundleContext.getServiceReferences(HttpService.class.getName(), null);
    HttpService httpService = null;
    if (httpReferences != null) {
        httpService = (HttpService) bundleContext.getService(httpReferences[0]);
    } else {
        logger.info("No http service available");
    }

    if ((trainingService != null) &#038;&#038; (httpService != null)) {
        logger.info("training servlet will be registered.");
        httpService.<strong>registerServlet</strong>("/trainings", new TrainingsServlet(trainingService), null, null);
        httpService.<strong>registerResources</strong>("/","/htmls",null);
    } else {
        logger.info("No servlet to register, problem with training service or http service");
    }
}

<strong>private void doRegister()</strong> {
    try {
        register();
    } catch (InvalidSyntaxException e) {
        logger.error("Could not register servlet based on an Invalid Syntax",e);
    } catch (ServletException e) {
        logger.error("Could not register servlet based on an Servlet exception",e);
    } catch (NamespaceException e) {
        logger.error("Could not register servlet based on an Namespace exception",e);
    }
}
</pre>
<p>Concentrate on the register method. First we check for available training service references. If a reference is available, we get the actual service. Then the same is done for the http service. If both of them are availble, we use the http service to register a new servlet that accepts the training service to obtain trainings from. As you can see we first register the servlet, the two null parameters represent the servlet config parameters and the special HttpContext. By providing null a default context is created. We also register a folder with static resources. The first string is the path or alias where the user should access the resources. The second string is the path to the resources within the bundle. The final parameter is the same as for the servlet, the HttpContext, again null so the default value. There are to more methods I want to show, first for unregistering and second for handling change events.</p>
<pre>
<strong>private void unregister() throws InvalidSyntaxException</strong> {
    logger.info("Unregister a servlet");
    ServiceReference[] httpReferences = bundleContext.getServiceReferences(HttpService.class.getName(), null);
    if (httpReferences != null) {
        HttpService httpService = (HttpService) bundleContext.getService(httpReferences[0]);
        httpService.unregister("/trainings");
        httpService.unregister("/");
    }
}

<strong>private void doUnregister()</strong> {
    try {
        unregister();
    } catch (InvalidSyntaxException e) {
        logger.error("Could not unregister servlet",e);
    }
}

<strong>public void serviceChanged(ServiceEvent event)</strong> {
    String objectClass = ((String[]) event.getServiceReference().getProperty("objectClass"))[0];
    logger.info("Service change event occurred for : {}", objectClass );
    if (event.getType() == ServiceEvent.REGISTERED) {
        doRegister();
    } else if (event.getType() == ServiceEvent.UNREGISTERING) {
        doUnregister();
    } else if (event.getType() == ServiceEvent.MODIFIED) {
        doUnregister();
        doRegister();
    }
}
</pre>
<p>The unregister function is pretty obvious. So let&#8217;s have a better look at the serviceChanged method. I took the easy way out here. Just check the type of event. In case of a new registration, register the servlet and resources. In case of an unregistration, we unregister the servlet and in case of a change we just do an unregister and a register. This works oke for my situation. Using the following screendumps I&#8217;ll show what happens when we start all bundles, stop de training-service bundle, and in the end start it again. First the output from the console, then the screens.</p>
<pre>
Welcome to Felix.
=================

1 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - No http service available
1 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - No servlet to register, problem with training service or http service
org.mortbay.log:Logging to org.mortbay.log via org.apache.felix.http.jetty.LogServiceLog
org.mortbay.log:started org.mortbay.jetty.servlet.HashSessionIdManager@2b2057
org.mortbay.log:started org.mortbay.jetty.servlet.HashSessionManager@85c0de
org.mortbay.log:starting OsgiServletHandler@395aaf
org.mortbay.log:started OsgiServletHandler@395aaf
org.mortbay.log:starting SessionHandler@70b819
org.mortbay.log:started SessionHandler@70b819
org.mortbay.log:starting org.mortbay.jetty.servlet.Context@1b50a1{/,null}
org.mortbay.log:starting ErrorHandler@46ad8b
org.mortbay.log:started ErrorHandler@46ad8b
org.mortbay.log:started org.mortbay.jetty.servlet.Context@1b50a1{/,null}
org.mortbay.log:jetty-6.1.x
org.mortbay.log:started Realm[OSGi HTTP Service Realm]==[]
org.mortbay.log:started org.mortbay.thread.BoundedThreadPool@ebaf12
org.mortbay.log:starting Server@32e910
org.mortbay.log:started org.mortbay.jetty.nio.SelectChannelConnector$1@19549e
org.mortbay.log:Started SelectChannelConnector@0.0.0.0:9081
org.mortbay.log:started SelectChannelConnector@0.0.0.0:9081
org.mortbay.log:started Server@32e910
191 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Service change event occurred for : org.osgi.service.http.HttpService
191 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - training servlet will be registered.
org.mortbay.log:started /trainings/*
org.mortbay.log:started /htmls
-> stop 1
36499 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Service change event occurred for : nl.gridshore.samples.bundles.trainingservice.api.TrainingService
36499 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Unregister a servlet
-> start 1
org.mortbay.log:started /trainings/*
org.mortbay.log:started /htmls
43500 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Service change event occurred for : nl.gridshore.samples.bundles.trainingservice.api.TrainingService
43500 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - training servlet will be registered.
->
</pre>
<p>Try to follow the steps, you can see the bundle containing the servlet starts before the training-service of the http-service. Then the change event is received and the servlet is registered. Next we stop the training service and the servlet is unregistered. And the servlet is registered again after a start of the training-service bundle (number 1).</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/felix-osgi-training-step1.jpg" alt="felix-osgi-training-step1.jpg" border="0" width="536" height="355"/>This is the initial screen. Notice the url, this is a static resource called index.html that loads a stylesheet and an image from the bundle.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/felix-osgi-training-step2.jpg" alt="felix-osgi-training-step2.jpg" border="0" width="536" height="356"/>Now we have stopped the training service bundle, which has resulted in a unregister of the servlet, therefore the page is not available anymore.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/felix-osgi-training-step3.jpg" alt="felix-osgi-training-step3.jpg" border="0" width="537" height="355"/>I have started the training service bundle again, so the servlet gets registered and now I have clicked the link for trainings. As you can see we have two very interesting trainings.</p>
<p>So that is about it, it turned out to become a pretty long post. Hope you liked it. Please leave a comment if you did, and of course if you did not. All your ideas and suggestions are welcome. If you want to have a look at the source, you can find everyting in the FelixTryout project at my <a href="http://code.google.com/p/gridshore/source/browse">google code website</a>. </p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F02%2F29%2Fcreating-a-jetty-based-osgi-httpservice-for-apache-felix%2F&amp;title=Creating%20a%20jetty%20based%20OSGi%20HttpService%20for%20apache%20felix&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Embedding Jetty in OSGi (osgi felix sample step 3)</title>
		<link>http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/</link>
		<comments>http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/#comments</comments>
		<pubDate>Fri, 15 Feb 2008 15:41:03 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[servlet]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/</guid>
		<description><![CDATA[<p>This is my third post in the osgi basics series. The topic of today is embedding a servlet container within an osgi container. Of course I am continuing to use felix and now I start using jetty from mortbay. Starting from version 6.1.x, jetty is packaged as a bundle in itself. It is very [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/logo1.png" alt="logo.png" border="0" width="165" height="63" align="left" />This is my third post in the osgi basics series. The topic of today is embedding a servlet container within an osgi container. Of course I am continuing to use felix and now I start using <a href="http://www.mortbay.org/">jetty from mortbay</a>. Starting from version 6.1.x, jetty is packaged as a bundle in itself. It is very easy to start a jetty instance within a felix container. Some steps we are going to take in this tutorial:
</p>
<p></p>
<ol>
<li>initialize the container with the required bundles.</li>
<li>Start up the jetty instance with a servlet listening to the default path</li>
<li>Add a servlet that uses a service and takes care of the lifecycle.</li>
</ol>
<h3>Setting up the context</h3>
<p>I already talked in my previous post about starting felix and adding bundles to the context. The following block of code shows the bundles that we install after initialization. I install the training service and the sample client. The sample client contains the code to start jetty and install the servlet. Then there are three jars you need to install before you are able to use the jetty instance: jetty, jetty-util and servlet api. Beware, if you want to use jsp&#8217;s as well you need to add more jars. Check the following website: <a href="http://docs.codehaus.org/display/JETTY/Embedding+Jetty">embedding jetty</a>.
</p>
<pre>
configMap.put(AutoActivator.AUTO_START_PROP + ".1",
    "file:" + BUNDLE_ROOT + "training-service/1.0-SNAPSHOT/training-service-1.0-SNAPSHOT.jar " +
    "file:" + BUNDLE_ROOT + "example-client/1.0-SNAPSHOT/example-client-1.0-SNAPSHOT.jar " +
    "file:" + JETTY_ROOT + "jetty/6.1.7/jetty-6.1.7.jar " +
    "file:" + JETTY_ROOT + "jetty-util/6.1.7/jetty-util-6.1.7.jar " +
    "file:" + JETTY_ROOT + "servlet-api-2.5/6.1.7/servlet-api-2.5-6.1.7.jar " +
    "file:bundle/slf4j-api-1.4.3.jar " +
    "file:bundle/slf4j-simple-1.4.3.jar " +
    "file:bundle/org.apache.felix.shell-1.0.0.jar " +
    "file:bundle/org.apache.felix.shell.tui-1.0.0.jar ");
</pre>
<h3>Start the jetty instance</h3>
<p><img src="http://www.gridshore.nl/wp-content/uploads/jetty-logo.gif" alt="jetty_logo.gif" border="0" width="269" height="112" align="right" /><br />
Starting a jetty instance is very easy. The following code shows you how to create a jetty instance while listening to a certain port. Next step is to initialize the context using a context url. In our case we use the root, so you should go to http://localhost:8091/ to have a look at the application. Second step is to add a HelloServlet instance listening to everything in the root path &#8220;/*&#8221;. The final step before actually starting the jetty instance might be a little less obvious. Here we define an empty servlet returning a non available message. The next step will show why. This servlet will be listening to the url &#8220;/trainings&#8221;
</p>
<pre>
Server server = new Server(9081);
Context root = new Context(server, JETTY_CONTEXT_PATH, Context.SESSIONS);
root.addServlet(new ServletHolder(new HelloServlet()), MAIN_SERVLET_PATH_SPEC);
servletHolder = new ServletHolder();
servletHolder.setServlet(new NonAvailableServlet());
root.addServlet(servletHolder, TRAININGS_SERVLET_PATH_SPEC);
server.start();
</pre>
<h3>Add training servlet if service is available</h3>
<p>We start by registering a service listener that is listening to events related to objects with a name TrainingService : </p>
<pre>
bundleContext.addServiceListener(this,
    "(&#038;(objectClass=" + TrainingService.class.getName() + "))");
</pre>
<p>You can add other properties to this query, but for now we do not need that. Since the activator class implements the <strong>ServiceListener</strong> interface we need to implement the following method. That method receives events that comply to the provided filter.
</p>
<pre>
public void serviceChanged(ServiceEvent event) {
    if (event.getType() == ServiceEvent.REGISTERED) {
        logger.info("Training service is registered");
        servletHolder.setServlet(new TrainingsServlet(
            (TrainingService)bundleContext.getService(event.getServiceReference())));
    } else if (event.getType() == ServiceEvent.UNREGISTERING) {
        logger.info("Training service is unregistered");
        servletHolder.setServlet(new NonAvailableServlet());
    } else if (event.getType() == ServiceEvent.MODIFIED) {
        logger.info("Training service is modified");
        servletHolder.setServlet(new TrainingsServlet(
            (TrainingService)bundleContext.getService(event.getServiceReference())));
    }
}
</pre>
<p>
As you can see from the code there are three type of events we support. We get an event when the service is registered, unregistered or changed. This gives us the opportunity to register the servlet that uses the training service if the service is available and to register the empty servlet when the training service is not available.
</p>
<p>
You can find the complete source code <a href="http://code.google.com/p/gridshore/source/browse">here</a> (look for the FelixTryout project). and the specific Activator containing the jetty stuff <a href="http://code.google.com/p/gridshore/source/browse/trunk/FelixTryout/example-client/src/main/java/nl/gridshore/samples/bundles/exampleclient/impl/Activator.java">here</a>.
</p>
<p>
That is about it, hope you liked the article. Use the comments if you have questions. If you would like to read the previous articles, click on them here or click on felix in the tag cloud.<br />
<a href="http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/">step 1</a> &#8211; <a href="http://www.gridshore.nl/2008/02/13/using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2/">step 2</a></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F02%2F15%2Fembedding-jetty-in-osgi-osgi-felix-sample-step-3%2F&amp;title=Embedding%20Jetty%20in%20OSGi%20%28osgi%20felix%20sample%20step%203%29&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using maven to create an osgi bundle (osgi felix sample step 2)</title>
		<link>http://www.gridshore.nl/2008/02/13/using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2/</link>
		<comments>http://www.gridshore.nl/2008/02/13/using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 08:58:30 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2008/02/13/using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2/</guid>
		<description><![CDATA[<p>This is the second step in a series of items about exploring the felix osgi container and some sidesteps to make life easier while developing osgi bundles. You can find the first step here: http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/</p> <p>This is so easy, I do not want to spend to much time here. There is a special maven [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/logo1.png" alt="logo.png" border="0" width="165" height="63" align="left" />This is the second step in a series of items about exploring the felix osgi container and some sidesteps to make life easier while developing osgi bundles. You can find the first step here: http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/</p>
<p>This is so easy, I do not want to spend to much time here. There is a special maven 2 plugin to create a &#8220;bundle&#8221;, check out the following page that describes the plugin :<a href="http://felix.apache.org/site/maven-bundle-plugin-bnd.html"> maven-bundle-plugin</a>.</p>
<p>Create a new maven project using the most basic archetype.</p>
<p>mvn archetype:create -DgroupId=&lt;your.groupid&gt; -DartifactId=&lt;your.artifactId&gt;</p>
<p>Change the packaging of the pom to be &quot;bundle&quot;. Add a dependency to the core and configure the plug in. The possible parameters are described extensively at the mentioned web page. I&#8217;ll explain the what and why of the code below, not the theory. The following pom file is the pom of the project example-client in the FelixTryout project on my <a href="http://code.google.com/p/gridshore/source/browse">google code</a> page. As you can see there is a dependency on the training-service and on jetty. i am not going to talk about jetty here. More on that in one of the next steps.</p>
<pre>
&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;groupId&gt;nl.gridshore.samples.bundles&lt;/groupId&gt;
    &lt;artifactId&gt;example-client&lt;/artifactId&gt;
    &lt;packaging&gt;bundle&lt;/packaging&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;name&gt;example-client&lt;/name&gt;
    &lt;url&gt;http://maven.apache.org&lt;/url&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;${pom.groupId}&lt;/groupId&gt;
            &lt;artifactId&gt;training-service&lt;/artifactId&gt;
            &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.felix&lt;/groupId&gt;
            &lt;artifactId&gt;org.osgi.core&lt;/artifactId&gt;
            &lt;version&gt;1.0.0&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
            &lt;artifactId&gt;jetty&lt;/artifactId&gt;
            &lt;version&gt;6.1.7&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;source&gt;1.5&lt;/source&gt;
                    &lt;target&gt;1.5&lt;/target&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.felix&lt;/groupId&gt;
                &lt;artifactId&gt;maven-bundle-plugin&lt;/artifactId&gt;
                &lt;version&gt;1.2.0&lt;/version&gt;
                &lt;extensions&gt;true&lt;/extensions&gt;
                &lt;configuration&gt;
                    &lt;instructions&gt;
                        &lt;Export-Package&gt;
                            nl.gridshore.samples.bundles.exampleclient.api
                        &lt;/Export-Package&gt;
                        &lt;Private-Package&gt;
                            nl.gridshore.samples.bundles.exampleclient.impl
                        &lt;/Private-Package&gt;
                        &lt;Bundle-SymbolicName&gt;${pom.artifactId}&lt;/Bundle-SymbolicName&gt;
                        &lt;Bundle-Activator&gt;
                            nl.gridshore.samples.bundles.exampleclient.impl.Activator
                        &lt;/Bundle-Activator&gt;
                    &lt;/instructions&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;
&lt;/project&gt;
</pre>
<p>The export-package contains the packages that are exposed to other bundles. This results in the following manifest file:</p>
<pre>
Manifest-Version: 1.0
Built-By: jettro
Created-By: Apache Maven Bundle Plugin
Bundle-Activator: nl.gridshore.samples.bundles.exampleclient.impl.Acti
 vator
Import-Package: javax.servlet;version="2.5",javax.servlet.http;version
 ="2.5",nl.gridshore.samples.bundles.trainingservice.api,org.mortbay.j
 etty;version="6.1",org.mortbay.jetty.servlet;version="6.1",org.osgi.f
 ramework;version="1.3"
Bnd-LastModified: 1202823580612
Bundle-Version: 1.0.0.SNAPSHOT
Bundle-Name: example-client
Build-Jdk: 1.5.0_13
Private-Package: nl.gridshore.samples.bundles.exampleclient.impl
Bundle-ManifestVersion: 2
Bundle-SymbolicName: example-client
Tool: Bnd-0.0.227
</pre>
<p>Most of the items are pretty obvious if you look at the maven configuration. There is one thing that is more advanced. Have a look at the import-Package, this contains the packages that are imported by the classes. This is done automatically by the bundle plugin. You can prevent imports by configuring the &quot;ImportPackage&quot; and use the negative import.</p>
<p>&lt;Import-Package&gt;!org.foo.impl&lt;/Import-Package&gt;</p>
<p>That is about it, mvn clean install and your plugin is installed into the maven repository. Well, of course you do need to implement some java code. Just like I said before, you can find the implementation on google code. I will also introduce the concepts in the forthcoming steps or posts.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F02%2F13%2Fusing-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2%2F&amp;title=Using%20maven%20to%20create%20an%20osgi%20bundle%20%28osgi%20felix%20sample%20step%202%29&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/02/13/using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Starting with OSGi using apache felix (step 1)</title>
		<link>http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/</link>
		<comments>http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/#comments</comments>
		<pubDate>Sun, 10 Feb 2008 19:29:18 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/</guid>
		<description><![CDATA[<p>I think it was somewhere September 2006 when I first read about OSGi. Immediately I saw opportunities to finally come to my long envisioned Service Component Architecture. On top of that I could fix all these classloader issues as well. So good news. Together with Allard we started evaluating the possibilities of OSGi. We [...]]]></description>
			<content:encoded><![CDATA[<p><img height="63" style="margin: 5px; float: left" width="165" alt="" src="http://www.gridshore.nl/wp-content/logo.png" />I think it was somewhere September 2006 when I first <a href="http://www.springframework.org/osgi/specification">read about OSGi</a>. Immediately I saw opportunities to finally come to my long envisioned Service Component Architecture. On top of that I could fix all these classloader issues as well. So good news. Together with Allard we started evaluating the possibilities of OSGi. We tried starting with <a href="http://www.springframework.org/osgi">spring osgi</a> (I know the name has changed, but this is easier), but we were missing some basic knowledge. So back to the roots, use pure OSGi. Because we were using eclipse for a long time, we started using <a href="http://www.eclipse.org/equinox/">equinox.</a> We even have given a <a href="http://www.nljug.org/pages/events/content/jspring_2007/sessions/00003/">presentation about OSGi in combination with webservice versioning</a> at a dutch java user conference. Because I wanted to use maven and since I am programming with IntelliJ nowadays I was looking for other options. That is when I got back to felix, which has become a very interesting project. After this long introduction it is time to start explaining what this post is all about. With this post I want to share my first steps with apache felix. Watch out for all other posts about the OSGi felix exploration.</p>
<p>First a general idea about the thing we are going to create and the steps to take.<img height="89" style="margin: 5px; float: right" width="186" alt="" src="http://www.gridshore.nl/wp-content/top1.gif" /></p>
<ol>
<li>Start a felix instance using java code and interact with the OSGi context from outside</li>
<li>Create bundles using maven 2</li>
<li>Create a service that is exposed as a bundle</li>
<li>Create a simple client</li>
</ol>
<p>In other posts I want to look at more enterprise possibilities, like exposing using the web, etc. Most of the knowledge I gained for this article I took from the felix website. There are some nice pages about creating bundles, using services, registering listeners. Check their <a href="http://felix.apache.org/site/apache-felix-osgi-tutorial.html">OSGi pages</a>.</p>
<p><strong><span style="font-size:16pt">Embed the OSGi container in your application</span></strong></p>
<p>This section is about starting felix from your code and interact with the OSGi context. I am not going to discuss the complete configuration options, I&#8217;ll focus on the most easiest possible way to make it work. You can find <a href="http://felix.apache.org/site/launching-and-embedding-apache-felix.html">detailed information on this page</a>. When initializing the felix container you must provide the configuration properties and the activators for the container. Felix provides a special implementation of a TreeMap called the org.apache.felix.framework.util.StringMap. This is a map created to work purely with spring comparison. The following piece of code shows the code for creating the map.</p>
<pre>
Map&lt;String,String&gt; configMap = new StringMap(false);
configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true");
configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES,
    "org.osgi.framework; version=1.3.0," +
    "org.osgi.service.packageadmin; version=1.2.0," +
    "org.osgi.service.startlevel; version=1.0.0," +
    "org.osgi.service.url; version=1.0.0");
configMap.put(AutoActivator.AUTO_START_PROP + ".1",
    "file:" + PATH_TO_MAVEN_REPO + "service-listener-1.0-SNAPSHOT.jar " +
    "file:" + PATH_TO_MAVEN_REPO + "training-service-1.0-SNAPSHOT.jar " +
    "file:" + PATH_TO_MAVEN_REPO + "example-client-1.0-SNAPSHOT.jar " +
    "file:bundle/org.apache.felix.shell-1.0.0.jar " +
    "file:bundle/org.apache.felix.shell.tui-1.0.0.jar ");
configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP, "cache");
</pre>
<p>There are four part in this configuration:</p>
<ol>
<li>System packages that are exported by the framework to become available to other bundles</li>
<li>Embedded execution, only used when you embed the Felix container in another java application</li>
<li>AutoActivator, used to install bundles right after starting the container</li>
<li>Bundle cache, where to place the cached bundles</li>
</ol>
<p>As you can see we install 5 bundles, three of my own that I am going to use in the application and two as provided by the felix framework. The next few lines of code show you how to actually start the felix instance. We create a list of activators that are installed during the context initialization. A special activator is the AutoActivator. This is configured in the properties object as stated above. There we have configured the AutoActivator as well.</p>
<pre>
List activators = new ArrayList();
activators.add(new AutoActivator(configMap));
activator = new HostActivator();
activators.add(activator);
felix = new Felix(configMap, activators);
try {
    felix.start();
} catch (BundleException e) {
    System.err.println("Could not create framework: " + e);
    e.printStackTrace();
    System.exit(-1);
}
</pre>
<p>If you look at the code you can see we initialize another activator as well. This is the HostActivator. An interesting way to create a hook in the felix container from a class outside of the application. The following piece of code shows this special activator. Check the method getBundles, this method returns a reference to all available bundles. The launcher has access to this class and can therefore call the activator while not actually being part of the felix container.</p>
<pre>
public class HostActivator implements BundleActivator {
    private BundleContext context = null;

    public void start(BundleContext bundleContext) throws Exception {
        context = bundleContext;
    }

    public void stop(BundleContext bundleContext) throws Exception {
        context = null;
    }

    public Bundle[] getBundles() {
        Bundle[] bundles = null;
        if (context != null) {
            bundles = context.getBundles();
        }
        return bundles;
    }
}
</pre>
<p>You can have a look at the complete sources online at the google code website:</p>
<p><a href="http://code.google.com/p/gridshore/source/browse">http://code.google.com/p/gridshore/source/browse</a> &#8211; check the FelixTryout project.</p>
<p>This is a first step in a number of steps I am going to post. The next step will be about using maven to create a new OSGi bundle.<br />
<a href="http://www.gridshore.nl/2008/02/13/using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2/">using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2</a></p>
<p style="color:#008;text-align:right;"><small><em>Powered by</em> <a href="http://www.qumana.com/">Qumana</a></small></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F02%2F10%2Fstarting-with-osgi-using-apache-felix-step-1%2F&amp;title=Starting%20with%20OSGi%20using%20apache%20felix%20%28step%201%29&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

