<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3096964353090017094</id><updated>2011-12-29T06:10:47.792+01:00</updated><category term='server'/><category term='maven'/><category term='android'/><category term='tests'/><category term='osgi'/><category term='release'/><category term='ipojo'/><category term='junit4osgi'/><category term='native'/><category term='apachecon'/><category term='en'/><category term='devcon'/><title type='text'>iPOJO's Dark Side</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-5145787484526008448</id><published>2009-08-03T17:18:00.004+02:00</published><updated>2009-08-03T17:36:04.716+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'></title><content type='html'>&lt;h1&gt;An iPOJO 1.4.0 overview&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;Finally! The last week, the iPOJO team released the iPOJO 1.4.0 version of the framework. This new version fixed several bugs but also provides new features.  This post gives on overview of the novelties provided in this opus.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The API to describe iPOJO component type in Java&lt;/h2&gt;&lt;br /&gt;iPOJO supports XML &amp; annotation based descriptions. The iPOJO API provides a way to create /declare new component types &amp; instances at runtime. This is a very convenient way against annotations and XML allergies! This API was designed to be easy to use, avoids redundancies… Here a small example creating a service provider and a service consumer:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void create(BundleContext bc) throws Exception { &lt;br /&gt; new PrimitiveComponentType()&lt;br /&gt;  .setBundleContext(bc)&lt;br /&gt;  .setClassName(HelloServiceProvider.class.getName())&lt;br /&gt;  .addService(new Service()&lt;br /&gt;   .addProperty(&lt;br /&gt;    new ServiceProperty().setName("language")&lt;br /&gt;    .setType(String.class.getName())&lt;br /&gt;    .setValue("en")&lt;br /&gt;   ))&lt;br /&gt;  .createInstance();&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; new PrimitiveComponentType()&lt;br /&gt;  .setBundleContext(bc)&lt;br /&gt;  .setClassName(HelloServiceConsumer.class.getName())&lt;br /&gt;  .addDependency(new Dependency().setField("hello"))&lt;br /&gt;  .setValidateMethod("start")&lt;br /&gt;  .createInstance();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The POJO classes are manipulated at runtime if required. &lt;br /&gt;An interesting property of the API is the iPOJO composite support. So you can easily describe applications natively dynamic. To illustrate that, let’s imagine a pretty simple application compared by 2 instances from 2 types (potentially described with the API). This application is described and instantiated as follow: &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; new CompositeComponentType()&lt;br /&gt;        .setBundleContext(bc)&lt;br /&gt;        .addInstance(new Instance("MyProviderType"))&lt;br /&gt;        .addInstance(new Instance("MyConsumerType"))&lt;br /&gt;        .createInstance();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Last but not least, the API is bound with the introspection and reconfiguration mechanism of iPOJO. For reconfiguration adepts (Autonomic, context-aware applications), it simplifies the reconfiguration process. Thanks to this feature, it is pretty easy to declare a component type, create an instance of this type, and then, later, reconfigure its service dependency:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;    Dependency dependency = new Dependency().setField("hello");&lt;br /&gt;    ComponentInstance instance = new PrimitiveComponentType()&lt;br /&gt;        .setBundleContext(bc)&lt;br /&gt;        .setClassName(HelloServiceConsumer.class.getName())&lt;br /&gt;        .addDependency(dependency)&lt;br /&gt;        .setValidateMethod("start")&lt;br /&gt;        .createInstance();&lt;br /&gt;        &lt;br /&gt;    dependency.getDependencyDescription(instance).setFilter(bc.createFilter("(language=en)"));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Interesting, isn’t it? And that’s just an overview! &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;Online Manipulator&lt;/h2&gt;&lt;br /&gt;The second great novelty is the online manipulator. Let’s sum up the story. A lot of users were complaining about the additional packaging step to create iPOJO bundle. This step prepares the bundle to be managed by iPOJO. So despite tools such as Ant and Maven doing this preparation seamlessly (once configured), it’s trickier with tools as Eclipse. The online manipulator just removes this additional step. In fact, it does this process during the deployment of the bundle. To use, the online manipulator, just prefix your bundle URL with &lt;tt&gt;ipojo://&lt;/tt&gt;. That’s it. It looks for the&lt;tt&gt; metadata.xml&lt;/tt&gt; file inside the bundle and executes manipulation. You can also specify or override the metadata in the URL:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;install ipojo:file:/tmp/mybundle.jar!file:/tmp/mymetadata.xml&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Thanks to the online manipulator, you can use any tools to develop your bundle such as the Eclipse PDE. Just awesome!&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Web Console Plugin&lt;/h2&gt;&lt;br /&gt;Finally, the last novelty is really interesting for those development complex applications with iPOJO. The Web Console Plugin is an Apache Felix Web Console extension giving data about your iPOJO applications. &lt;br /&gt;It’s a Web based alternative to the «arch» command. The plugin displays the created instances, available factories and handlers. For all those entities, details are given such as the current state, provided services (and properties), used services…  The model is navigable! So, for a service dependency, you can directly navigate to the used iPOJO instance, from an instance, you can switch to the factory (i.e. component type) and see all the instances from this type. For «arch» command user, the « raw » architecture is also given. This plugin definitively helps debugging iPOJO applications by giving everything required to understand the reasons to unsatisfied service dependencies, invalid instances or factories.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_fTY6niaFaAc/SncC43wuplI/AAAAAAAAFkE/7reWJt5RO4w/s1600-h/instance-list.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 94px;" src="http://3.bp.blogspot.com/_fTY6niaFaAc/SncC43wuplI/AAAAAAAAFkE/7reWJt5RO4w/s320/instance-list.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5365760657099499090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_fTY6niaFaAc/SncDLwJG8gI/AAAAAAAAFkM/nS12nSN0MnU/s1600-h/instance-detail.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 182px;" src="http://3.bp.blogspot.com/_fTY6niaFaAc/SncDLwJG8gI/AAAAAAAAFkM/nS12nSN0MnU/s320/instance-detail.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5365760981471785474" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;That’s all for the biggest novelties of iPOJO 1.4.0. It’s not only improvements. See the release notes for &lt;a href="https://cwiki.apache.org/jira/browse/FELIX/fixforversion/12313642"&gt;more details&lt;/a&gt;.&lt;br /&gt;Moreover, the road map of the next version is also promising: proxy support, constructor injection, transaction support and persistence. And that’s just a couple of example. So one advice, stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-5145787484526008448?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/5145787484526008448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=5145787484526008448' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/5145787484526008448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/5145787484526008448'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/08/ipojo-1.html' title=''/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_fTY6niaFaAc/SncC43wuplI/AAAAAAAAFkE/7reWJt5RO4w/s72-c/instance-list.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-2984880536250460818</id><published>2009-06-26T10:34:00.003+02:00</published><updated>2009-06-26T10:44:58.422+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android talk at Linuxtag</title><content type='html'>Yesterday I gave with Karl Pauls a talk about Android at &lt;a href="http://www.linuxtag.org/2009/en.html"&gt;Linuxtag&lt;/a&gt;.&lt;br /&gt;It was great: 70 to 80 people, a lot of questions ...&lt;br /&gt;I just updated the slide, so, if you're interested by Android and maybe OSGi, just have a &lt;a href="http://www.slideshare.net/clement.escoffier/android-a-linuxbased-os-for-mobile-phone"&gt;look&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px;text-align:left" id="__ss_1642585"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/clement.escoffier/android-a-linuxbased-os-for-mobile-phone?type=presentation" title="Android : a linux-based mobile operating system"&gt;Android : a linux-based mobile operating system&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=android-090626030135-phpapp02&amp;stripped_title=android-a-linuxbased-os-for-mobile-phone" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=android-090626030135-phpapp02&amp;stripped_title=android-a-linuxbased-os-for-mobile-phone" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/clement.escoffier"&gt;clement.escoffier&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-2984880536250460818?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/2984880536250460818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=2984880536250460818' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2984880536250460818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2984880536250460818'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/06/android-talk-at-linuxtag.html' title='Android talk at Linuxtag'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-1673836843407343077</id><published>2009-06-23T16:28:00.003+02:00</published><updated>2009-06-23T16:37:38.558+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='devcon'/><title type='text'>OSGi devcon Talks</title><content type='html'>Just back from OSGi Dev Con Europe. The conference was great and the talk quality was very good. Here are my presentations:&lt;br /&gt;&lt;br /&gt;&lt;div style="width: 425px; text-align: left;" id="__ss_1625515"&gt;&lt;a style="margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; display: block; text-decoration: underline;" href="http://www.slideshare.net/clement.escoffier/transactional-osgi-applications-done-right?type=presentation" title="Transactional OSGi Applications Done Right"&gt;Transactional OSGi Applications Done Right&lt;/a&gt;&lt;object style="margin: 0px;" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=transactionalosgiapplicationsdoneright-distrib-090623085838-phpapp01&amp;amp;stripped_title=transactional-osgi-applications-done-right"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=transactionalosgiapplicationsdoneright-distrib-090623085838-phpapp01&amp;amp;stripped_title=transactional-osgi-applications-done-right" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;"&gt;View more &lt;a style="text-decoration: underline;" href="http://www.slideshare.net/"&gt;OpenOffice presentations&lt;/a&gt; from &lt;a style="text-decoration: underline;" href="http://www.slideshare.net/clement.escoffier"&gt;clement.escoffier&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px;text-align:left" id="__ss_1625522"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/clement.escoffier/experimenting-with-the-osgi-platform-in-the-aspire-rfid-middleware?type=presentation" title="Experimenting with the OSGi platform in the Aspire RFID middleware"&gt;Experimenting with the OSGi platform in the Aspire RFID middleware&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=osgidevcon-june2009-aspire-090623090119-phpapp01&amp;stripped_title=experimenting-with-the-osgi-platform-in-the-aspire-rfid-middleware" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=osgidevcon-june2009-aspire-090623090119-phpapp01&amp;stripped_title=experimenting-with-the-osgi-platform-in-the-aspire-rfid-middleware" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;OpenOffice presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/clement.escoffier"&gt;clement.escoffier&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can look at the others presentation on &lt;a href="http://www.slideshare.net/group/osgi-devcon-europe-09"&gt;OSGi devcon Europe 2009 group&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-1673836843407343077?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/1673836843407343077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=1673836843407343077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/1673836843407343077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/1673836843407343077'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/06/osgi-devcon-talks.html' title='OSGi devcon Talks'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-808551909655179283</id><published>2009-05-03T09:12:00.002+02:00</published><updated>2009-05-03T09:19:19.488+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='junit4osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='tests'/><title type='text'>The Junit4OSGi - Pax:Exam mix</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;span style="font-style: italic;"&gt;Half of both, shake, enjoy …&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;In the OSGi world, there is different ways to test “&lt;span style="font-style: italic;"&gt;bundles&lt;/span&gt;” / “&lt;span style="font-style: italic;"&gt;systems&lt;/span&gt;” / “&lt;span style="font-style: italic;"&gt;applications&lt;/span&gt;”.&lt;br /&gt;&lt;br /&gt;Spring Integration Testing fit very well with Spring applications, but in all the others cases it doesn’t work very well.&lt;br /&gt;&lt;br /&gt;BND Testing Harness is a testing framework integrated with BND. Despite very powerful to generate bundle on the fly, it sounds not very adequate when test must be integrated inside a build process expect Ant and Eclipse (such as Maven).&lt;br /&gt;&lt;br /&gt;Junit4osgi is a very simple test framework, running junit 3 tests on OSGi. The goal was to provide a simple way to write tests checking services … junit4osgi also provides high-level method simplifying the OSGi test writing.&lt;br /&gt;&lt;br /&gt;Finally, pax:exam is a test framework for OSGi allowing to finely configure the test framework.&lt;br /&gt;&lt;br /&gt;Recently, I discuss with the pax:exam developers about providing THE test framework for OSGi. In fact, I was considering moving the iPOJO test suites and the application test suites that I developed to pax:exam. After trying pax:exam, I was finally able to understand what pax:exam provides and what would be great…&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Requirements&lt;/span&gt;&lt;br /&gt;First what are the requirements of a cool test framework for OSGi.&lt;br /&gt;&lt;br /&gt;To begin, it has to reuse existing “test engine” such as junit or testNG. Java developers have already developed tests with those frameworks (I hope so…), and so this should ease the OSGi test writing.&lt;br /&gt;&lt;br /&gt;Then, as you know, testing is never a very exiting task. So, the test framework should provide high-level methods to ease the OSGi integration.  Methods such as “&lt;span style="font-style: italic;"&gt;getService&lt;/span&gt;”, “&lt;span style="font-style: italic;"&gt;waitForService&lt;/span&gt;” … should be provided and so the developer can focus on testing its service and not how to get the service.&lt;br /&gt;&lt;br /&gt;Third important point: the configuration. The application/service have to be deployed and run is a “real” OSGi platform. This platform has to be configured. This configuration contains obviously the bundles to deploy but can also contain other properties (extra packages, system configuration…). Supporting several OSGi implementation and several dependent bundle package is also a good property.&lt;br /&gt;&lt;br /&gt;Another important aspect related to the configuration is the dispatching test / platform. This should allow configuring which tests have to be deployed and execute on the SAME frameworks. Despite this can create side effects; sometimes we are looking for those side effects.&lt;br /&gt;&lt;br /&gt;The test framework must provide a “seamless” integration with build process and development tools such as Ant, Maven, Eclipse…  Tests should be executed when the project is built, and developer should be able to execute quickly their tests from their favorite IDE.&lt;br /&gt;&lt;br /&gt;OSGi defines Execution-Environment. The minimum environment is J2ME Foundation Profile 1.1. The test framework should provide a mode allowing executing test on this environment. Indeed, sometimes we want to check that everything works on a production-like environment or on different Java Virtual Machine.&lt;br /&gt;&lt;br /&gt;Finally, the test framework should provide a way to execute the test manually on a “regular” platform. This way allows debugging what does not work. The developer recreates the environment or uses the production environment, deploys its tests and executes them manually.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Junit4osgi / pax:exam : The comparison&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Test Engine&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Junit4OSGi: junit3 only&lt;/li&gt;&lt;li&gt;Pax:Exam: sub-set of junit4 (no afterClass and beforeClass), possibility to support others test engines.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;High-Level method&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Junit4OSGi: Helper pattern (osgi (bundle, service, package admin), ipojo, config admin, event admin…)&lt;/li&gt;&lt;li&gt;Pax:Exam: just the bundle context&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Configuration&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Junit4OSGi: all maven dependencies that are bundles + system properties. Use Felix only&lt;/li&gt;&lt;li&gt;Pax:Exam: @Configure method allowing to finely configure that framework (provisioning, Maven helper…). Allow running test on several configuration (OSGi implementation…).&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Platform / Test&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Junit4OSGi: one framework per Maven project &lt;/li&gt;&lt;li&gt;Pax:Exam: One framework per @Test method&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Build Process / IDE integration&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Junit4OSGi: Maven integration, possibility to manually launch the tests&lt;/li&gt;&lt;li&gt;Pax:Exam: Maven, any IDE (at least Eclipse)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Execution-Environment&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Junit4OSGi: J2ME Foundation Profile 1.1&lt;/li&gt;&lt;li&gt;Pax:Exam: Java 5&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Manual launching&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Junit4OSGi: Yes, all the tests are inside a bundle&lt;/li&gt;&lt;li&gt;Pax:Exam: No, must use the regular test runner&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Diving into pax:exam&lt;/span&gt;&lt;br /&gt;I recently tried pax:exam and developed a couple of tests with it. It is really a promising framework, and the integration of the junit4osgi features is now on the roadmap. However, I have a couple of complaints and solutions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;pax:exam fits very well to test OSGi applications, but to test framework we need a way to create on the fly bundles. Pax:exam does not provide natively such kind of feature. However, Tony Menzel developed tinybundle, a small and simple API to create bundle on the fly. I extended it a little bit to support iPOJO bundles. So, I’m able to create iPOJO bundles on the fly inside my tests! Definitely great.&lt;/li&gt;&lt;li&gt;The pax:exam development model relies on the bundle context. As a junit4osgi power user, I want high-level method. I just externalized junit4OSGi helpers, and so was able to reuse all the junit4osgi methods.&lt;/li&gt;&lt;li&gt;Pax:Exam is definitely slow… As it creates one framework per @Test method, it’s really inefficient when your test suite contains thousands of tests. I have 2000 tests with junit4osgi. Executing all of them takes almost 5 minutes (I have very expensive test with asynchronous event handling…). I also have a test suite developed with pax:exam of 20 tests. Such suite is executed in 3 minutes. So, there is definitely a performance / time issue. However, the pax:exam team is developing a Felix container as the junit4osgi one. This will improve performance. &lt;/li&gt;&lt;li&gt;A way to execute junit3 tests (working on Foundation Profile 1.1) and TestNG tests would be great. &lt;/li&gt;&lt;li&gt;A way to create test bundles “deployable” manually on a manually configured platform&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So, in conclusion, pax:exam is a promising framework. I’m looking forward the next improvements and hope that junit4OSGi features will be provided soon.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Resources&lt;/span&gt;&lt;br /&gt;Junit4osgi: &lt;a href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html"&gt;http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html&lt;/a&gt;&lt;br /&gt;Pax:exam: &lt;a href="http://wiki.ops4j.org/display/paxexam/Pax+Exam"&gt;http://wiki.ops4j.org/display/paxexam/Pax+Exam&lt;/a&gt;&lt;br /&gt;BND Testing Harness: &lt;a href="http://felix.apache.org/site/bnd-testing-harness.html"&gt;http://felix.apache.org/site/bnd-testing-harness.html&lt;/a&gt;&lt;br /&gt;Spring Integration Testing: &lt;a href="http://springosgi.googlepages.com/ch04.html"&gt;http://springosgi.googlepages.com/ch04.html&lt;/a&gt;&lt;br /&gt;Junit 3: &lt;a href="http://junit.sourceforge.net/junit3.8.1/index.html"&gt;http://junit.sourceforge.net/junit3.8.1/index.html&lt;/a&gt;&lt;br /&gt;Junit 4: &lt;a href="http://www.junit.org"&gt;http://www.junit.org&lt;/a&gt;&lt;br /&gt;TestNG: &lt;a href="http://testng.org"&gt;http://testng.org&lt;/a&gt;&lt;br /&gt;Helper class to ease test writing: &lt;a href="http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/api/src/test/java/org/apache/felix/ipojo/tests/api/"&gt;http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/api/src/test/java/org/apache/felix/ipojo/tests/api/&lt;/a&gt;&lt;br /&gt;Tinybundle: &lt;a href="https://scm.ops4j.org/repos/ops4j/projects/pax/swissbox/pax-swissbox-tinybundles/"&gt;https://scm.ops4j.org/repos/ops4j/projects/pax/swissbox/pax-swissbox-tinybundles/&lt;/a&gt;&lt;br /&gt;iPOJO extension to tinybundle: &lt;a href="http://svn.apache.org/viewvc/felix/sandbox/clement/BundleAsiPOJO/"&gt;http://svn.apache.org/viewvc/felix/sandbox/clement/BundleAsiPOJO/&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-808551909655179283?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/808551909655179283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=808551909655179283' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/808551909655179283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/808551909655179283'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/05/junit4osgi-paxexam-mix.html' title='The Junit4OSGi - Pax:Exam mix'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-5825908495807096366</id><published>2009-04-14T19:01:00.004+02:00</published><updated>2009-04-14T19:08:44.151+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>Customized service object creation with iPOJO</title><content type='html'>The last week, I attended to the OSGi in Action talk organized by the Java User Group Berlin – Brandenburg.  Karl did a very nice talk, but I was definitely more interested by the questions ☺&lt;br /&gt;One of the questions was about the service object creation policy. The person asking for this, was a little worried by the default OSGi policy: publishing the service object itself in the service registry. I can understand his issue: why creating something not necessary needed (lazy creation), and how can I deal with multiple service objects.&lt;br /&gt;&lt;br /&gt;So, the answer is definitely the Service Factory. When publishing a service factory instead of the service object, the framework notifies you each time a NEW bundle asks for a service object. So, you can create the service object at the first call or create one service object each time a new bundle asks for the service. In fact, the OSGi framework caches the returned object in order to improve performance.&lt;br /&gt;&lt;br /&gt;However, it’s weird to add this “bundle” concept there. How I can create one service object per call or per user, or per thread? Those creation policies make sense in a lot of context. The traditional OSGi answer relies on the “Facade” design pattern. You registers an object that delegate the invocation on the “good” object. You can create the “good” object regarding to your creation policy.&lt;br /&gt;&lt;br /&gt;However, I was never really happy to implement this facade pattern in the code. Why? Just because it’s typically something that:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Pollute your code&lt;/li&gt;&lt;li&gt;Can be externalized&lt;/li&gt;&lt;/ol&gt;Inside iPOJO, I tried to remove this limitation by adding a third creation policy. It is possible to provide a service and to create one service object per asking instance. So, two instances will use two different service object despite they are in the same bundle!&lt;br /&gt;&lt;br /&gt;In fact, iPOJO provides a way to specify your own creation strategy. Imagine that you have a specific creation policy. Just implement the desired behavior by creating a class extending &lt;a href="http://felix.apache.org/ipojo/api/1.2.0/org/apache/felix/ipojo/handlers/providedservice/CreationStrategy.html"&gt;CreationStrategy&lt;/a&gt;. Moreover, iPOJO brings a new concept called &lt;a href="http://felix.apache.org/ipojo/api/1.2.0/org/apache/felix/ipojo/IPOJOServiceFactory.html"&gt;IPojoServiceFactory&lt;/a&gt; closed to OSGi Service Factory but based on instance. So, if an iPOJO instance requires a service implementing this interface, the iPOJO container will call a special method to get the service object. This method will be called every time the service is get (so not only once per instance). However the creation strategy may decide to return always the same service object for one instance (per instance strategy).&lt;br /&gt;&lt;br /&gt;So, how I can create my own fine-grained creation policy?&lt;br /&gt;&lt;br /&gt;Just create a class extending the CreationStrategy class and implements the IPOJOServiceFactory interface.&lt;br /&gt;&lt;br /&gt;So, let’s say that your OSGi Service Factory getService method is called. So you return a proxy/facade extending the IPOJO Service Factory interface like in&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public Object getService(Bundle arg0, ServiceRegistration arg1) {&lt;br /&gt;            Object proxy = Proxy.newProxyInstance(getInstanceManager().getClazz().getClassLoader(),&lt;br /&gt;                    getSpecificationsWithIPOJOServiceFactory(m_serviceSpecification, m_handler.getInstanceManager().getContext()), this);&lt;br /&gt;            return proxy;&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When another iPOJO instance will asks for your service, it will call the iPOJO Service Factory getService method. Then, you intercept this method and apply your creation strategy.  For example, the next snippet shows the per instance creation strategy:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public Object invoke(Object arg0, Method arg1, Object[] arg2) {&lt;br /&gt;            if (isGetServiceMethod(arg1)) {&lt;br /&gt;                return getService((ComponentInstance) arg2[0]);&lt;br /&gt;            }&lt;br /&gt;           &lt;br /&gt;            if (isUngetServiceMethod(arg1)) {&lt;br /&gt;                ungetService((ComponentInstance) arg2[0], arg2[1]);&lt;br /&gt;                return null;&lt;br /&gt;            }&lt;br /&gt;           &lt;br /&gt;            throw new UnsupportedOperationException("This service requires an advanced creation policy. "&lt;br /&gt;                    + "Before calling the service, call the getService(ComponentInstance) method to get "&lt;br /&gt;                    + "the service object. ");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        public Object getService(ComponentInstance instance) {&lt;br /&gt;            Object obj = m_instances.get(instance);&lt;br /&gt;            if (obj == null) {&lt;br /&gt;                obj = m_handler.getInstanceManager().createPojoObject();&lt;br /&gt;                m_instances.put(instance, obj);&lt;br /&gt;            }&lt;br /&gt;            return obj;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;public void ungetService(ComponentInstance instance, Object svcObject) {&lt;br /&gt;            Object pojo = m_instances.remove(instance);&lt;br /&gt;            m_handler.getInstanceManager().deletePojoObject(pojo);&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can easily change this code to implement your own strategy like one per thread... As you get the ComponentInstance object, you can easily look for properties… and so create very sophisticated strategies.&lt;br /&gt;&lt;br /&gt;So, thanks to this mechanism, you can creation you own policy and refer to it from your provides metadata:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;    &amp;lt;component&lt;br /&gt;        classname="…FooBarProviderType"&amp;gt;&lt;br /&gt;        &amp;lt;provides strategy="….MyCreationStrategy"&amp;gt;&lt;br /&gt;    &amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That’s it!&lt;br /&gt;&lt;br /&gt;The main and major limitation of these strategies is that they rely on iPOJO. So both the provider and the consumer have to be developed with iPOJO to deal correctly with the new service object creation policy. So, just use iPOJO ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-5825908495807096366?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/5825908495807096366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=5825908495807096366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/5825908495807096366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/5825908495807096366'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/04/customized-service-object-creation-with.html' title='Customized service object creation with iPOJO'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-4621783839184454425</id><published>2009-04-01T17:10:00.007+02:00</published><updated>2009-04-01T17:30:38.055+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><title type='text'>iPOJO and File Install : configuring iPOJO instances with 'cfg' files</title><content type='html'>&lt;a href="http://felix.apache.org/site/apache-felix-file-install.html"&gt;FileInstall&lt;/a&gt; is a great bundle to provision your system. It watches a directory and installs every bundles contained inside the directory. Moreover, it’s fully support the configuration admin. So, it reads .cfg files contained in the folder and pushes the read configuration into the configuration admin.&lt;br /&gt;&lt;br /&gt;iPOJO also supports the configuration admin. iPOJO instances can be created, deleted and reconfigured from the configuration admin.&lt;br /&gt;&lt;br /&gt;So, why not creating, reconfiguring and deleting iPOJO instances from the &lt;span style="font-style: italic;"&gt;cfg&lt;/span&gt; files.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;File Install philosophy&lt;/h3&gt; &lt;br /&gt;File install is great and simple. It just has one general idea to understand:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-style: italic;"&gt;The content of the watched folder is your system configuration&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So, if you create &lt;span style="font-style: italic;"&gt;cfg&lt;/span&gt; files inside this folder, those files will be analyzed and the configuration pushed in the configuration admin. To remove the configuration, just remove the file from the folder!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Note: Don’t forget to install the configuration admin &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Using File install to create instances&lt;/h3&gt;&lt;br /&gt;When you declare an iPOJO component, this will expose a &lt;span style="font-style: italic;"&gt;ManagedServiceFactory&lt;/span&gt; service. [Except if you voluntary set the component type to private]. This service can be used to create / reconfigure/ delete instances of this component type.&lt;br /&gt;&lt;br /&gt;So, let’s say that we have the following bar.Foo class:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Component&lt;br /&gt;public class Foo {&lt;br /&gt; @Property&lt;br /&gt; private String name;&lt;br /&gt;&lt;br /&gt; …&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This declare an iPOJO component type (named &lt;span style="font-style: italic;"&gt;bar.Foo&lt;/span&gt; (i.e. the &lt;span style="font-style: italic;"&gt;classname&lt;/span&gt;) as no name is specified). This component type also declares a property (&lt;span style="font-style: italic;"&gt;name&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;So, once deployed, iPOJO will exposed a &lt;span style="font-style: italic;"&gt;ManagedServiceFactory&lt;/span&gt; service with the &lt;span style="font-style: italic;"&gt;‘bar.Foo’&lt;/span&gt; &lt;span style="font-style: italic;"&gt;service pid&lt;/span&gt;. The configuration admin will push all matching configuration to this &lt;span style="font-style: italic;"&gt;ManagedServiceFactory&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Now, let’s say that File install watches the ‘&lt;span style="font-style: italic;"&gt;load&lt;/span&gt;’ folder. If you create a file named&lt;span style="font-style: italic;"&gt; bar.Foo-1.cfg&lt;/span&gt; containing the following content:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;name = the name&lt;br /&gt;&lt;/pre&gt;Once saved, File Install will find it, analyzes it and pushes the configuration to the configuration admin. The configuration admin will pushes this configuration to our &lt;span style="font-style: italic;"&gt;ManagedServiceFactory&lt;/span&gt;, and so we just create an instance of our type!&lt;br /&gt;&lt;br /&gt;So, &lt;span style="font-style: italic;"&gt;cfg&lt;/span&gt; files completely replaces the &lt;instance&gt; tag of iPOJO metadata files. You no more need them (if you use annotations).&lt;br /&gt;&lt;br /&gt;Let’s create a second file named bar.Foo-2.cfg containing the following content:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;name = the second name&lt;br /&gt;&lt;/pre&gt;This will create another instance.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Reconfiguring an instance&lt;/h3&gt;&lt;br /&gt;To reconfigure an instance, just edit the &lt;span style="font-style:italic;"&gt;cfg&lt;/span&gt; file. For example, edit the &lt;span style="font-style:italic;"&gt;bar.Foo-2.cfg&lt;/span&gt; and change the name property to &lt;span style="font-style:italic;"&gt;‘a third name’&lt;/span&gt;. The instance will be automatically reconfigured.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Deleting an instance&lt;/h3&gt;&lt;br /&gt;To delete an instance, just remove the &lt;span style="font-style:italic;"&gt;cfg&lt;/span&gt; file (containing the instance configuration) from the file install folder. That’s it! The watched folder is your system configuration.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The ManagedService case&lt;/h3&gt;&lt;br /&gt;So, let’s imagine that you don’t want to create instances from &lt;span style="font-style:italic;"&gt;cfg&lt;/span&gt; file but just reconfiguring them. It’s also possible. File install also supports &lt;span style="font-style:italic;"&gt;Managed Service&lt;/span&gt;, and so, will pushed a &lt;span style="font-style:italic;"&gt;Managed Service&lt;/span&gt; configuration inside the configuration admin.&lt;br /&gt;&lt;br /&gt;If you use this way, you have to create the instance yourself (from the &lt;span style="font-style:italic;"&gt;metadata.xml&lt;/span&gt; file for example).&lt;br /&gt;First, let’s modify our component type:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Component(managedservice="MyPID")&lt;br /&gt;public class Foo {&lt;br /&gt; @Property&lt;br /&gt; private String name;&lt;br /&gt;&lt;br /&gt; …&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and create the metadata.xml file declaring an instance of this type:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;ipojo&amp;gt;&lt;br /&gt;&amp;lt;instance component="bar.Foo"/&amp;gt;&lt;br /&gt;&amp;lt;/ipojo&amp;gt&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The “managedservice” attribute of the @Component annotation allows setting the service pid of the Managed Service.  So, iPOJO will expose a ManagedService allowing reconfiguring your instance with the “MyPID” pid. [You can also set the managedservice pid from the &lt;a href="http://felix.apache.org/site/configuration-handler.html#ConfigurationHandler-ExposingaManagedService"&gt;instance configuration&lt;/a&gt;].&lt;br /&gt;So, to reconfigure the instance, create a cfg file named MyPID.cfg containing the configuration such as:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;name = a name&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When you save the file in the watched folder, File install will pushes the configuration to the configuration admin. Then, the configuration admin will look for the matching &lt;span style="font-style:italic;"&gt;ManagedService&lt;/span&gt; (the one with the MyPID service.pid) and pushed the configuration. So, your instance will receives the configuration!&lt;br /&gt;&lt;br /&gt;To edit the configuration, just edit the &lt;span style="font-style:italic;"&gt;cfg&lt;/span&gt; file. To remove it, just remove the file from the folder.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;File install is definitely a great tool to provision your system. The configuration admin supports can be useful to create iPOJO applications “on the fly” and will allows you reconfiguring your system dynamically!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-4621783839184454425?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/4621783839184454425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=4621783839184454425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/4621783839184454425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/4621783839184454425'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/04/ipojo-and-file-install-configuring.html' title='iPOJO and File Install : configuring iPOJO instances with &apos;cfg&apos; files'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-1305468258601262161</id><published>2009-03-29T12:52:00.001+02:00</published><updated>2009-03-29T12:54:26.579+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='junit4osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='apachecon'/><title type='text'>Back from Amsterdam</title><content type='html'>So, I’m back from ApacheCon. It was a great conference with high quality talks. OSGi was really a hot topic. &lt;br /&gt;&lt;br /&gt;I organized an Apache Felix BOF with Felix, Carsten and Marcel. 30 people attend this BOF. This definitely illustrates the OSGi wave. I posted a &lt;a href="http://www.nabble.com/ApacheCon-EU-Felix-BOF-td22739690.html"&gt;BOF report&lt;/a&gt; on the Felix dev mailing list.&lt;br /&gt;&lt;br /&gt;Another surprise is the feedbacks I get about junit4OSGi. It definitely seems to be the missing piece in OSGi development! So, my goal is now to release it soon (April). I recently improved the doc (now available from the &lt;a href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html"&gt;iPOJO web site&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;I have a couple of ideas about junit4osgi evolution. I will work on a better maven integration (site generation), in a way to do in-container tests, supporting other test ‘frameworks' such as junit4 or testNG… My discussions about these leads with junit4osgi users definitely interest them. So, here we go!&lt;br /&gt;&lt;br /&gt;To summary ApacheCon in three words: &lt;span style="font-weight: bold;"&gt;“it was awesome!”&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-1305468258601262161?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/1305468258601262161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=1305468258601262161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/1305468258601262161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/1305468258601262161'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/03/back-from-amsterdam.html' title='Back from Amsterdam'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-4409910528649222949</id><published>2009-03-16T11:48:00.003+01:00</published><updated>2009-03-16T11:52:44.354+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><title type='text'>ApacheCon EU / EclipseCon</title><content type='html'>The next week, I will be at &lt;a href="http://www.eu.apachecon.com/c/aceu2009/"&gt;ApacheCon EU&lt;/a&gt;  in Amsterdam from Wednesday to Friday.  If you have questions about iPOJO, pervasive or mobile applications, or if you just want to drink a beer, feel free to contact me.&lt;br /&gt;&lt;br /&gt;If you prefer the sunny California to Amsterdam, Karl Pauls and Richard Hall will be at EclipseCon. Don’t hesitate to ask them iPOJO related questions.  Moreover, do not miss their "&lt;a href="http://www.eclipsecon.org/2009/sessions?id=360"&gt;OSGi in Action&lt;/a&gt;" tutorial.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-4409910528649222949?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/4409910528649222949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=4409910528649222949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/4409910528649222949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/4409910528649222949'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/03/apachecon-eu-eclipsecon.html' title='ApacheCon EU / EclipseCon'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-2373378248586402445</id><published>2009-03-06T11:10:00.000+01:00</published><updated>2009-03-06T11:12:57.595+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='native'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='junit4osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='tests'/><title type='text'>Maven, OSGi, and native libraries on Mac OS</title><content type='html'>I’m currently involved in a project dealing with native library. As a software engineering fan, I decide to set a project containing both unitary tests and integration test (thanks to the maven-junit4osgi-plugin, of course ☺).&lt;br /&gt;&lt;br /&gt;However yesterday a strange issue appeared. The integration tests using the native library were executed “successfully”, but when I ran the same bundles in our application, I get &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/UnsatisfiedLinkError.html"&gt;UnsatisfiedLinkError&lt;/a&gt;. For all of you that already meet this Exception, it is always a bad thing.&lt;br /&gt;&lt;br /&gt;What really does it means? No native libraries match with the actual architecture/os/… or if one matches it cannot be loaded for an obscured reason.&lt;br /&gt;&lt;br /&gt;Hum, but I ran junit4osgi and the regular application on the same machine, my Mac book pro with Mac OS X! So, why junit4osgi was able to load the library and not a normal Felix platform (using exactly the same bundles)?&lt;br /&gt;&lt;br /&gt;It takes at least 3 hours of debugging to understand what happened. First, I claimed against Maven ☺ (as everyday!), but in fact Maven was not guilty (just a little bit, because it is Maven). I also tried the application on Felix and Equinox. Despite Equinox was a little more verbose on the issue, the library was not loaded. I try different version of Felix, and always the same error: UnsatisfiedLinkError ! The worst thing happened when one of my co-worker executed the application on Windows correctly!&lt;br /&gt;&lt;br /&gt;WTF????&lt;br /&gt;&lt;br /&gt;Junit4OSGi test reports contain the system properties, and so I decided to compare the properties between junit4osgi and the normal runtime. And here arrived the light: maven and the runtime does not use the same JVM.&lt;br /&gt;&lt;br /&gt;The OS provides the ‘mvn’ executable.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Clement-Escoffier:integration-test clement$  which mvn&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;/Users/clement/dev/apache-maven-2.0.9/bin/mvn&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This executable uses Java 5 (the default JVM on Mac). So when running maven-junit4osgi-plugin, it uses this 32bits VM. In this context, the native library was loaded correctly.&lt;br /&gt;&lt;br /&gt;However, when I ran the application, I use a Java 6 VM (64bits architecture). In this case, the library cannot be loaded. Despite it match the native library clause of my bundle; the library was not compiled to run on a 64bits CPU.&lt;br /&gt;&lt;br /&gt;So finally, three hours spend for just a JAVA_HOME issue…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-2373378248586402445?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/2373378248586402445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=2373378248586402445' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2373378248586402445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2373378248586402445'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/03/maven-osgi-and-native-libraries-on-mac.html' title='Maven, OSGi, and native libraries on Mac OS'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-6238421152153024965</id><published>2009-02-23T09:11:00.001+01:00</published><updated>2009-02-23T09:14:12.780+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><title type='text'>iPOJO available on Module Fusion</title><content type='html'>&lt;a href="http://code.google.com/p/modulefusion/"&gt;Module Fusion&lt;/a&gt; is an OSGi based stack for enterprise applications. The goal of ModuleFusion is to help programmers to use the OSGi Service Platform as their underlying runtime environment.&lt;br /&gt;&lt;br /&gt;ModuleFusion contains a full stack typical for Java enterprise applications. This stack currently consists of best-of-breed open source frameworks from the Java ecosystem. Additionally, ModuleFusion contains the necessary glue code to easily use these frameworks within OSGi.&lt;br /&gt;Probably the most important principle of ModuleFusion is to base every integration, glue code and additional functionality on pure OSGi constructs. Therefore, ModuleFusion does not rely on proprietary features offered by some OSGi framework implementations.&lt;br /&gt;&lt;br /&gt;The last week, I discuss with Roman about the possibility to integrate iPOJO in Module Fusion. So, now you can get an &lt;a href="http://modulefusion.googlecode.com/files/modulefusion-featurepack-iPOJO-1.1.0.zip"&gt;iPOJO feature pack&lt;/a&gt;, containing:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;iPOJO 1.2.0&lt;/li&gt;&lt;li&gt;The ‘arch’ command&lt;/li&gt;&lt;li&gt;The temporal dependency handler&lt;/li&gt;&lt;/ul&gt;You can also get &lt;a href="http://code.google.com/p/modulefusion/wiki/iPOJOExampleApplications"&gt;some examples&lt;/a&gt; about how to use iPOJO in Module fusion. More specially, a complete example about how using JPA (Hibernate) with iPOJO is provided.&lt;br /&gt;&lt;br /&gt;For iPOJO early adopter using iPOJO 1.3.0-SNAPSHOT, a Wicket web application using iPOJO dependencies injection is also provided. This is for early adopter only because of the &lt;a href="https://cwiki.apache.org/jira/browse/FELIX-936"&gt;Felix-936&lt;/a&gt; feature.  This new feature is used to exposed the web application in the OSGi registry and so allows Pax:Web to publish it.&lt;br /&gt;&lt;br /&gt;So, if you’re interested in OSGi on the server side, or on domain-specific OSGi based application servers, have a look to Module Fusion and see how iPOJO can help you in your daily development tasks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-6238421152153024965?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/6238421152153024965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=6238421152153024965' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/6238421152153024965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/6238421152153024965'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2009/02/ipojo-available-on-module-fusion.html' title='iPOJO available on Module Fusion'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-900433932316247325</id><published>2008-12-09T18:31:00.003+01:00</published><updated>2008-12-09T18:44:39.347+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='en'/><category scheme='http://www.blogger.com/atom/ns#' term='tests'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Code coverage of OSGi applications</title><content type='html'>The question that disturbs me last night is about test quantity/quality. So, when I can say: « Ok, I’ve enough tests ». So, for sure, this question is open.&lt;br /&gt;&lt;br /&gt;Freddy Mallet posted a comment on my last post about Sonar. Sonar (&lt;a href="http://sonar.codehaus.org/"&gt;http://sonar.codehaus.org/&lt;/a&gt;) is an all-in-one code quality tracker. So, based on maven (and a set of plug-ins), it collects data about your code, tests … and assembles reports on one web site with useful metrics (efficiency, usability…).&lt;br /&gt;&lt;br /&gt;I tested today and was really impressed. But, my code coverage metrics was desperately 0 ☹&lt;br /&gt;After some web searches, I found the Cobertura maven plug-in (&lt;a href="http://mojo.codehaus.org/cobertura-maven-plugin/"&gt;http://mojo.codehaus.org/cobertura-maven-plugin/&lt;/a&gt;) collecting code coverage during test execution thanks to the Cobertura framework (&lt;a href="http://cobertura.sourceforge.net/"&gt;http://cobertura.sourceforge.net/&lt;/a&gt;). However, as my systems and applications are tested in an OSGi container with junit4osgi, I investigated how to collect the code coverage of tests executed with juni4osgi.&lt;br /&gt;&lt;br /&gt;So, first it is possible after a very small hack of junit4osgi to manage cobertura packages.&lt;br /&gt;Collecting the code coverage is a three-step process:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;A] Creates a bundle with instrumented classes&lt;/span&gt;&lt;br /&gt;First you need to select ONE project under test. You will collect metrics on this project. So you want several projects, you need to execute the process several times (one per project).&lt;br /&gt;Once selected, edit the pom file to ignore the ‘net.sourceforge.cobertura.* packages such as in:&lt;br /&gt;&lt;pre name="code" class="Xml"&gt;&lt;br /&gt;&lt;import-package&gt;&lt;br /&gt;  org.osgi.framework;version=1.3,&lt;br /&gt;  org.osgi.service.cm,&lt;br /&gt;  org.osgi.service.log,&lt;br /&gt;  !net.sourceforge.cobertura.*&lt;br /&gt;&lt;/import-package&gt;&lt;br /&gt;&lt;/pre&gt;Then, execute the following command to create the instrumented bundle:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;mvn clean install cobertura:instrument package install&lt;br /&gt;&lt;/pre&gt;This command creates the bundle with the Cobertura instrumented code, and installs it in the local maven repository. Moreover, it creates a file containing code metadata in the &lt;span style="font-style: italic;"&gt;target/cobertura&lt;/span&gt; folder (&lt;span style="font-style: italic;"&gt;cobertura.ser&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;B] Test execution&lt;/span&gt;&lt;br /&gt;Once the bundle is created, you need to execute the test. The code coverage is computed during this execution. So to launch the execution, go in your integration-test project and execute the following command:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;mvn clean integration-test&lt;br /&gt;  -Dnet.sourceforge.cobertura.datafile&lt;br /&gt;      =/path/to/your/tested/project/target/cobertura/cobertura.ser&lt;br /&gt;&lt;/pre&gt;The &lt;span style="font-style: italic;"&gt;‘net.sourceforge.cobertura.datafile’&lt;/span&gt; property specified the location of the cobertura.ser file (created during the Cobertura code instrumentation).&lt;br /&gt;&lt;br /&gt;Tests are executed normally… But when maven is stopping, two messages appear:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;Cobertura: Loaded information on 81 classes.&lt;br /&gt;Cobertura: Saved information on 81 classes.&lt;br /&gt;&lt;/pre&gt;This means that the metrics were correctly collected.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;C] Generation of the report and analysis of the code coverage&lt;/span&gt;&lt;br /&gt;Once collected, go back to your tested project. To generate the report, just launch the following command:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;mvn cobertura:cobertura&lt;br /&gt;&lt;/pre&gt;The report is generated in the &lt;span style="font-style: italic;"&gt;target/site/cobertura/&lt;/span&gt; folder. &lt;a href="http://people.apache.org/%7Eclement/blog/cobertura/"&gt;Here&lt;/a&gt; is an example of generated report. You can also check your code coverage with:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;mvn cobertura:check&lt;br /&gt;&lt;/pre&gt;This doesn’t create the report but just gives an idea of the code coverage. You can use the cobertura plug-in &lt;a href="http://mojo.codehaus.org/cobertura-maven-plugin/usage.html"&gt;configuration&lt;/a&gt; to adapt the checking or the report to your requirements.&lt;br /&gt;&lt;br /&gt;That’s it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-900433932316247325?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/900433932316247325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=900433932316247325' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/900433932316247325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/900433932316247325'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2008/12/collection-code-coverage-of-osgi.html' title='Code coverage of OSGi applications'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-2601875485638165895</id><published>2008-12-06T14:48:00.004+01:00</published><updated>2008-12-06T14:58:28.366+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='en'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Reducing the pain of a release process</title><content type='html'>Who never crack down during a release process? Despite several tools ease the process; it’s generally a nightmare.&lt;br /&gt;&lt;br /&gt;Why? Because of the number of task to execute during the process: the product has to be deeply tested before the release, then license/notice files have to be checked as well as license header, the release candidates artifacts have to be created, deployed, signed, don’t forget the release note, and to update the documentation…&lt;br /&gt;&lt;br /&gt;So, I recently discover two maven plug-ins reducing (a little) the pain. They automate two checks: license headers and the code style consistency.&lt;br /&gt;&lt;br /&gt;First the checkstyle plug-in (&lt;a href="http://maven.apache.org/plugins/maven-checkstyle-plugin/"&gt;http://maven.apache.org/plugins/maven-checkstyle-plugin/&lt;/a&gt;) checks that your code is consistently formatted. It is, in my opinion, a critical aspect. So, diving into an unknown code consistently formatted is really easier. Using the plug-in is quite simple. Add the following plug-in configuration in the &lt;span style="font-style: italic;"&gt;build&lt;/span&gt; section of your &lt;span style="font-style: italic;"&gt;pom&lt;/span&gt; file:&lt;br /&gt;&lt;pre name="code" class="Xml"&gt;&lt;br /&gt;&amp;lt;plugin&gt;&lt;br /&gt;&amp;lt;groupid&gt;org.apache.maven.plugins&amp;lt;/groupid&gt;&lt;br /&gt;    &amp;lt;artifactid&gt;maven-checkstyle-plugin&amp;lt;/artifactid&gt;&lt;br /&gt;    &amp;lt;configuration&gt;           &lt;br /&gt;        &amp;lt;enablerulessummary&gt;false&amp;lt;/enablerulessummary&gt;&lt;br /&gt;        &amp;lt;violationseverity&gt;warning&amp;lt;/violationseverity&gt;&lt;br /&gt;        &amp;lt;configlocation&gt;http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml&amp;lt;/configlocation&gt;&lt;br /&gt;    &amp;lt;/configuration&gt;&lt;br /&gt;&amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The ‘&lt;span style="font-style: italic;"&gt;violationSeverity&lt;/span&gt;’ attribute sets the severity level from which the project build failed. So, if the code format breaks a rule with a level superior or equals to the set value, the build process failed. (Check levels can be set in the checkstyle file). The ‘&lt;span style="font-style: italic;"&gt;configLocation&lt;/span&gt;’ attribute specifies the checkstyle file to use (containing the format rules).&lt;br /&gt;&lt;br /&gt;So, once your project has the correct configuration, just launch the following command:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;mvn checkstyle:check&lt;/pre&gt;&lt;br /&gt;to check if your project doesn’t break your format. If executed on a multi-module project, each module is checked (each module need to be configured).&lt;br /&gt;&lt;br /&gt;So, thanks to this plug-in, checking the code format consistency is quite simple and can be automate during your project build process.&lt;br /&gt;&lt;br /&gt;The second plug-in is the RAT plug-in (&lt;a href="http://mojo.codehaus.org/rat-maven-plugin/"&gt;http://mojo.codehaus.org/rat-maven-plugin/&lt;/a&gt;). RAT (&lt;a href="http://incubator.apache.org/rat/"&gt;http://incubator.apache.org/rat/&lt;/a&gt;), is a tool to improve accuracy and efficiency when checking releases. It is heuristic in nature: making guesses about possible problems. It will produce false positives and cannot find every possible issue with a release. It reports require interpretation, but can also be automated…&lt;br /&gt;&lt;br /&gt;In fact, RAT checks license header and tacks missing license. RAT provides a maven plug-in which can automate the missing license discovery during your build project. To use this plug-in, just add the following plug-in configuration in the &lt;span style="font-style: italic;"&gt;build&lt;/span&gt; section of your &lt;span style="font-style: italic;"&gt;pom&lt;/span&gt; file.&lt;br /&gt;&lt;pre name="code" class="Xml"&gt;&lt;br /&gt;&amp;lt;plugin&gt;&lt;br /&gt;&amp;lt;groupid&gt;org.codehaus.mojo&amp;lt;/groupid&gt;&lt;br /&gt;&amp;lt;artifactid&gt;rat-maven-plugin&amp;lt;/artifactid&gt;&lt;br /&gt;&amp;lt;configuration&gt;                &lt;br /&gt;    &amp;lt;excludesubprojects&gt;false&amp;lt;/excludesubprojects&gt;         &lt;br /&gt;    &amp;lt;useeclipsedefaultexcludes&gt;true&amp;lt;/useeclipsedefaultexcludes&gt;    &lt;br /&gt;    &amp;lt;usemavendefaultexcludes&gt;true&amp;lt;/usemavendefaultexcludes&gt;&lt;br /&gt;    &amp;lt;excludes&gt;&lt;br /&gt;        &amp;lt;param&gt;doc/**/*&amp;lt;/param&gt;&lt;br /&gt;        &amp;lt;param&gt;maven-eclipse.xml&amp;lt;/param&gt;&lt;br /&gt;        &amp;lt;param&gt;.checkstyle&amp;lt;/param&gt;&lt;br /&gt;        &amp;lt;param&gt;.externalToolBuilders/*&amp;lt;/param&gt;&lt;br /&gt;        &amp;lt;param&gt;LICENSE.*&amp;lt;/param&gt; &lt;br /&gt;        &amp;lt;param&gt;.fbprefs&amp;lt;/param&gt;&lt;br /&gt;    &amp;lt;/excludes&gt;&lt;br /&gt;&amp;lt;/configuration&gt;&lt;br /&gt;&amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This configuration will check that non-excluded files have a correct license header. It excludes maven files (&lt;span style="font-style: italic;"&gt;target&lt;/span&gt; folder), eclipse files (&lt;span style="font-style: italic;"&gt;.project,  .classpath&lt;/span&gt;). Those files don’t require a license, as they should not be on the source code repository. Then, others files can be excluded such as the doc folder (containing &lt;span style="font-style: italic;"&gt;html&lt;/span&gt; files and release notes, used license files (&lt;span style="font-style: italic;"&gt;LICENSE. *&lt;/span&gt;)... Extend the list (or modify it) according to your project.&lt;br /&gt;&lt;br /&gt;To check that you have no file without a license header, just execute the following command:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;mvn rat:check&lt;/pre&gt;&lt;br /&gt;The command failed if a corrupted file is detected. Executed on a multi-module project (each module need to be configured), it checks every module and failed as soon as a module has an invalid file.&lt;br /&gt;&lt;br /&gt;So, by using these plug-ins, you can continuously check the consistency of your code format and of the license headers. This is not wonderful, but at least do one’s share of the work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-2601875485638165895?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/2601875485638165895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=2601875485638165895' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2601875485638165895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2601875485638165895'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2008/12/reducing-pain-of-release-process.html' title='Reducing the pain of a release process'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-8080820157746102541</id><published>2008-11-24T12:17:00.005+01:00</published><updated>2008-11-24T12:47:34.534+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='en'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>22.7 Mb!</title><content type='html'>Today, all began perfectly.&lt;br /&gt;I moved the&lt;span style="font-style: italic;"&gt; junit4osgi plug-in&lt;/span&gt; to the iPOJO Trunk and decided with junit4osgi users to move the junit4osgi projects as ‘&lt;span style="font-style: italic;"&gt;iPOJO top level&lt;/span&gt;’ project. And, icing on the cake, I finished my PHD Defense slides.&lt;br /&gt;&lt;br /&gt;Moreover, I was pretty proud of my new script checking iPOJO current trunk:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;&lt;br /&gt;mkdir tmp&lt;br /&gt;cd tmp&lt;br /&gt;svn co https://svn.apache.org/repos/asf/felix/trunk/ipojo&lt;br /&gt;cd ipojo&lt;br /&gt;mvn clean install -Pexamples,tests&lt;br /&gt;mvn rat:check&lt;br /&gt;mvn checkstyle:check&lt;br /&gt;cd tests&lt;br /&gt;cd integration-tests&lt;br /&gt;mvn clean integration-test&lt;br /&gt;mvn org.apache.maven.plugins:maven-surefire-report-plugin:report&lt;br /&gt;/usr/bin/osascript -e 'tell application "Safari" to activate open location "file:/Users/clement/tmp/ipojo/tests/integration-tests/target/site/surefire-report.html"'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, I executed it from scratch (empty maven repository), and here arrives the issue …&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;22.7 Mb&lt;/span&gt; is the size of my maven repository after the execution of the script ! It just downloads and compiles iPOJO trunk (not the whole Felix project) and executes tests.&lt;br /&gt;&lt;br /&gt;After a quick analysis, some artifacts were downloaded in multiple versions. So, it’s time for me to track some of these artifacts, and to try to reduce this size. I’m pretty sure, that I can’t drastically reduce this mess, anyway, I’ll try.&lt;br /&gt;&lt;br /&gt;Here are the duplicated artifacts:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;&lt;br /&gt;commons-collections-2.1.jar&lt;br /&gt;commons-collections-3.2.jar&lt;br /&gt;commons-logging-1.0.3.jar&lt;br /&gt;commons-logging-1.0.4.jar&lt;br /&gt;commons-validator-1.1.4.jar&lt;br /&gt;commons-validator-1.2.0.jar&lt;br /&gt;org.osgi.compendium-1.0.0.jar&lt;br /&gt;org.osgi.compendium-1.2.0.jar&lt;br /&gt;org.osgi.core-1.0.0.jar&lt;br /&gt;org.osgi.core-1.0.1.jar&lt;br /&gt;org.osgi.core-1.2.0.jar&lt;br /&gt;org.osgi.foundation-1.0.0.jar&lt;br /&gt;org.osgi.foundation-1.2.0.jar&lt;br /&gt;doxia-core-1.0-alpha-10.jar&lt;br /&gt;doxia-core-1.0-alpha-8.jar&lt;br /&gt;doxia-decoration-model-1.0-alpha-10.jar&lt;br /&gt;doxia-decoration-model-1.0-alpha-11.jar&lt;br /&gt;doxia-decoration-model-1.0-alpha-8.jar&lt;br /&gt;doxia-site-renderer-1.0-alpha-10.jar&lt;br /&gt;doxia-site-renderer-1.0-alpha-8.jar&lt;br /&gt;maven-archiver-2.0.jar&lt;br /&gt;maven-archiver-2.2.jar&lt;br /&gt;maven-archiver-2.3.jar&lt;br /&gt;maven-artifact-2.0.jar&lt;br /&gt;maven-artifact-2.0.7.jar&lt;br /&gt;maven-artifact-manager-2.0.jar&lt;br /&gt;maven-artifact-manager-2.0.7.jar&lt;br /&gt;maven-model-2.0.jar&lt;br /&gt;maven-model-2.0.7.jar&lt;br /&gt;maven-plugin-api-2.0.jar&lt;br /&gt;maven-plugin-api-2.0.7.jar&lt;br /&gt;maven-profile-2.0.jar&lt;br /&gt;maven-profile-2.0.7.jar&lt;br /&gt;maven-project-2.0.jar&lt;br /&gt;maven-project-2.0.7.jar&lt;br /&gt;maven-repository-metadata-2.0.jar&lt;br /&gt;maven-repository-metadata-2.0.7.jar&lt;br /&gt;maven-jar-plugin-2.1.jar&lt;br /&gt;maven-jar-plugin-2.2.jar&lt;br /&gt;maven-plugin-plugin-2.3.jar&lt;br /&gt;maven-plugin-plugin-2.4.1.jar&lt;br /&gt;maven-surefire-plugin-2.3.jar&lt;br /&gt;maven-surefire-plugin-2.4.2.jar&lt;br /&gt;maven-reporting-impl-2.0.jar&lt;br /&gt;maven-reporting-impl-2.0.4.jar&lt;br /&gt;maven-reporting-impl-2.0.4.1.jar&lt;br /&gt;surefire-api-2.3.jar&lt;br /&gt;surefire-api-2.4.2.jar&lt;br /&gt;surefire-booter-2.3.jar&lt;br /&gt;surefire-booter-2.4.2.jar&lt;br /&gt;wagon-provider-api-1.0-alpha-5.jar&lt;br /&gt;wagon-provider-api-1.0-beta-2.jar&lt;br /&gt;plexus-archiver-1.0-alpha-3.jar&lt;br /&gt;plexus-archiver-1.0-alpha-7.jar&lt;br /&gt;plexus-archiver-1.0-alpha-9.jar&lt;br /&gt;plexus-container-default-1.0-alpha-8.jar&lt;br /&gt;plexus-container-default-1.0-alpha-9-stable-1.jar&lt;br /&gt;plexus-i18n-1.0-beta-6.jar&lt;br /&gt;plexus-i18n-1.0-beta-7.jar&lt;br /&gt;plexus-utils-1.0.4.jar&lt;br /&gt;plexus-utils-1.1.jar&lt;br /&gt;plexus-utils-1.4.jar&lt;br /&gt;plexus-utils-1.4.1.jar&lt;br /&gt;plexus-utils-1.4.4.jar&lt;br /&gt;plexus-utils-1.4.5.jar&lt;br /&gt;plexus-utils-1.4.7.jar&lt;br /&gt;plexus-utils-1.4.9.jar&lt;br /&gt;plexus-utils-1.5.1.jar&lt;br /&gt;plexus-velocity-1.1.2.jar&lt;br /&gt;plexus-velocity-1.1.3.jar&lt;br /&gt;plexus-velocity-1.1.7.jar&lt;br /&gt;oro-2.0.7.jar&lt;br /&gt;oro-2.0.8.jar&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-8080820157746102541?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/8080820157746102541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=8080820157746102541' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/8080820157746102541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/8080820157746102541'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2008/11/227-mb.html' title='22.7 Mb!'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-2899586091374975445</id><published>2008-11-11T09:59:00.011+01:00</published><updated>2008-12-07T09:51:49.845+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='en'/><category scheme='http://www.blogger.com/atom/ns#' term='tests'/><title type='text'>maven-junit4osgi-plugin</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; the &lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt; artifact has recently changed. The &lt;span style="font-style: italic;"&gt;groupID&lt;/span&gt; became &lt;span style="font-style: italic;"&gt;org.apache.felix&lt;/span&gt;. Moreover, the plugin is now in the &lt;span style="font-style: italic;"&gt;iPOJO trunk&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;In my last post, I explain the advantages of integrating integration test in the build process. However, such tools was inexistent until … now ☺&lt;br /&gt;&lt;br /&gt;As I explained, the &lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt; framework allows testing an OSGi applications with a "junit++" framework (i.e. an adapted &lt;a href="http://junit.org/"&gt;junit&lt;/a&gt; distribution providing useful methods to handle easily OSGi specific features such as services).&lt;br /&gt;&lt;br /&gt;But, the &lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt; framework is a “standalone” framework and is not integrated in a build tools such as Ant or Maven. This post describes a maven plug-in, &lt;span style="font-weight: bold;"&gt;maven-junit4osgi-plugin&lt;/span&gt;, executing tests in a maven-based build process.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Constraints of such tools&lt;/span&gt;&lt;br /&gt;Providing such front-end is useful but should meet some requirements:&lt;br /&gt;Tests are executed “in container”. So, tested bundles are really deployed on an OSGi framework (I choose Apache Felix). So tests are executing in an execution environment close to the final (production) execution environment. The goal of integration tests is to test the application in a production-like environment.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The project under construction is not a functional bundle, but can either be empty or contain integration tests. Integration tests are not placed in the same project as the project under test.  Integration tests are packaged inside others bundles deployed on the same framework as the application under test..&lt;/li&gt;&lt;li&gt;To recreate the “final” execution environment, several bundles can be required (technical services, the application under test…). So the plug-in must support the deployment of required bundles.&lt;/li&gt;&lt;li&gt;Test results must be reported to the user. Maven provides an infrastructure to create web site. Moreover, Surefire (the Maven “regular” test plug-in) provides a plug-in generating a web page with test result. The provided plug-in should provide the same features and should reuse the same format as Surefire.&lt;/li&gt;&lt;/ul&gt;The good news is that the provided plug-in, &lt;span style="font-weight: bold;"&gt;maven-junit4osgi-plugin&lt;/span&gt;, match these requirements!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;What does the&lt;span style="font-style: italic;"&gt; maven-junit4osgi-plugin&lt;/span&gt; provide?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Allows testing OSGi applications&lt;/li&gt;&lt;li&gt;Integrated in a Maven-based build process&lt;/li&gt;&lt;li&gt;Provides the same output as Surefire&lt;/li&gt;&lt;li&gt;Supports Maven site generation&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;Using the plug-in&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-size:100%;" &gt;Download and building the plug-in&lt;/span&gt;&lt;br /&gt;The plug-in sources are available in the iPOJO trunk.&lt;br /&gt;However the junit4osgi and iPOJO runtime are also required. So, download the source of iPOJO:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;svn co http://svn.apache.org/repos/asf/felix/trunk/ipojo/&lt;/pre&gt;To compile it, run the following commands:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;cd ipojo&lt;br /&gt;mvn clean install –Pexamples&lt;/pre&gt;(the –Pexamples allows compiling iPOJO examples and so the &lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt; framework ans the plug-in). Now you can use the plug-in in your project.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Simple configuration&lt;/span&gt;&lt;br /&gt;So, first the project using the plug-in is not the project under test. It’s another project containing either only integration-test packaged in a bundle, or is empty (and so depends on other bundles containing integration tests).&lt;br /&gt;Tests contained in the project are developed with &lt;a href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html"&gt;&lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt;&lt;/a&gt;, and are packaged in a bundle with the &lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html"&gt;maven-bundle-plugin&lt;/a&gt;.&lt;br /&gt;In the pom file, add the following plugin configuration to use the maven-junit4osgi-plugin:&lt;br /&gt;&lt;pre name="code" class="Xml"&gt;&lt;br /&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;&amp;lt;groupid&amp;gt;org.apache.felix&amp;lt;/groupid&amp;gt;&lt;br /&gt;&amp;lt;artifactid&amp;gt;maven-junit4osgi-plugin&amp;lt;/artifactid&amp;gt;&lt;br /&gt;&amp;lt;executions&amp;gt;&lt;br /&gt;&amp;lt;execution&amp;gt;&lt;br /&gt;&amp;lt;goals&amp;gt;&lt;br /&gt;      &amp;lt;goal&amp;gt;test&amp;lt;/goal&amp;gt;&lt;br /&gt;&amp;lt;/goals&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;lt;deployprojectartifact&amp;gt;true&amp;lt;/deployprojectartifact&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;lt;/execution&amp;gt;&lt;br /&gt;&amp;lt;/executions&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Plugin parameter&lt;/span&gt;&lt;br /&gt;The plug-in has only one parameter. The &lt;span style="font-style: italic;"&gt;'deployProjectArtifact'&lt;/span&gt; parameter enables or disables the current artifact deployment. If the current project contains tests, the plug-in can deploy the built artifact (as illustrated in &lt;a href="http://people.apache.org/%7Eclement/blog/poms/primitive.xml"&gt;this pom&lt;/a&gt;). Otherwise, the current project artifact is not deployed. This can be useful if the project just depends on other test bundles and sets the test configuration (as &lt;a href="http://people.apache.org/%7Eclement/blog/poms/ipojo-test.xml"&gt;this pom&lt;/a&gt;).&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;Configuring the set of bundles to deploy&lt;/span&gt;&lt;br /&gt;There is two different ways to configure the plug-in to deploy other bundles. If the bundle to deploy is a maven artifact, just add this artifact as a maven project dependency and set the dependency scope to ‘&lt;span style="font-style: italic;"&gt;test&lt;/span&gt;’. Here is an example:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;lt;artifactid&gt;tests.manipulation.metadata&amp;lt;/artifactid&amp;gt;&lt;br /&gt;&amp;lt;groupid&amp;gt;ipojo.tests&amp;lt;/groupid&amp;gt;&lt;br /&gt;&amp;lt;version&amp;gt;1.1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If your bundle is not a maven artifact, you can configure the plugin with the bundle URL (from where the bundle will be deployed)&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;lt;deployprojectartifact&amp;gt;true&amp;lt;/deployprojectartifact&amp;gt;&lt;br /&gt;&amp;lt;bundles&amp;gt;&lt;br /&gt;&amp;lt;param&amp;gt;file:/Users/clement/bundles/test-metadata.jar&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;lt;/bundles&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Set bundles are installed and started. You can depend on bundle that does not contain test as well as bundle containing tests.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;Executing the plug-in&lt;/span&gt;&lt;br /&gt;To execute test, just launch the &lt;span style="font-style: italic;"&gt;‘mvn clean integration-test’&lt;/span&gt; command.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;&lt;br /&gt;[INFO] Scanning for projects...&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] Building iPOJO Primitive Manipulation Test Suite&lt;br /&gt;[INFO]    task-segment: [integration-test]&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] [resources:resources]&lt;br /&gt;[INFO] Using default encoding to copy filtered resources.&lt;br /&gt;[INFO] [compiler:compile]&lt;br /&gt;[INFO] Nothing to compile - all classes are up to date&lt;br /&gt;[INFO] [resources:testResources]&lt;br /&gt;[INFO] Using default encoding to copy filtered resources.&lt;br /&gt;[INFO] [compiler:testCompile]&lt;br /&gt;[INFO] No sources to compile&lt;br /&gt;[INFO] [surefire:test]&lt;br /&gt;[INFO] No tests to run.&lt;br /&gt;[INFO] [bundle:bundle]&lt;br /&gt;[INFO] [ipojo:ipojo-bundle {execution: default}]&lt;br /&gt;[INFO] Start bundle manipulation&lt;br /&gt;[INFO] Metadata file : /Users/clement/Documents/workspaces/felix-trunk/ipojo/tests/manipulator/primitives/target/classes/metadata.xml&lt;br /&gt;[INFO] Input Bundle File : /Users/clement/Documents/workspaces/felix-trunk/ipojo/tests/manipulator/primitives/target/tests.manipulation.primitives-1.1.0-SNAPSHOT.jar&lt;br /&gt;[INFO] Bundle manipulation - SUCCESS&lt;br /&gt;[INFO] [junit4osgi:test {execution: default}]&lt;br /&gt;Analyzing org.apache.felix.ipojo - compile&lt;br /&gt;Analyzing org.apache.felix.ipojo.metadata - compile&lt;br /&gt;Analyzing org.osgi.core - compile&lt;br /&gt;Analyzing junit - compile&lt;br /&gt;Analyzing org.apache.felix.ipojo.junit4osgi - compile&lt;br /&gt;Analyzing tests.manipulation.metadata - test&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------&lt;br /&gt;T E S T S&lt;br /&gt;-------------------------------------------------------&lt;br /&gt;Deploy : /Users/clement/Documents/workspaces/felix-trunk/ipojo/tests/manipulator/primitives/target/tests.manipulation.primitives-1.1.0-SNAPSHOT.jar&lt;br /&gt;Loading org.apache.felix.ipojo.test.scenarios.manipulation.ManipulationTestSuite&lt;br /&gt;Loading org.apache.felix.ipojo.test.scenarios.manipulation.ManipulationTestSuite&lt;br /&gt;Junit Extender starting ...&lt;br /&gt;Running Manipulation Metadata Test Suite&lt;br /&gt;Tests run: 16, Failures: 0, Errors: 0, Time elapsed: 0 sec&lt;br /&gt;Running Primitive Manipulation Test Suite&lt;br /&gt;Tests run: 17, Failures: 0, Errors: 0, Time elapsed: 0 sec&lt;br /&gt;&lt;br /&gt;Results :&lt;br /&gt;&lt;br /&gt;Tests run: 33, Failures: 0, Errors:0&lt;br /&gt;&lt;br /&gt;Unload test suites [class org.apache.felix.ipojo.test.scenarios.manipulation.ManipulationTestSuite]&lt;br /&gt;Unload test suites [class org.apache.felix.ipojo.test.scenarios.manipulation.ManipulationTestSuite]&lt;br /&gt;Cleaning test suites ...&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] BUILD SUCCESSFUL&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] Total time: 6 seconds&lt;br /&gt;[INFO] Finished at: Mon Nov 10 21:30:21 CET 2008&lt;br /&gt;[INFO] Final Memory: 9M/18M&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Failures and errors are reported in the plugin output.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Generating the report web page&lt;/span&gt;&lt;br /&gt;When test are executed, the plug-in generates XML reports (int the t&lt;span style="font-style: italic;"&gt;arget/junit4osgi-reports directory&lt;/span&gt;) using the same convention as Surefire. So, it is possible to configure Surefire to generate the web page with test results.&lt;br /&gt;To do this, add the following report configuration to the project executing tests:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;reporting&amp;gt;&lt;br /&gt;&amp;lt;plugins&amp;gt;&lt;br /&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;&amp;lt;groupid&amp;gt;org.apache.maven.plugins&amp;lt;/groupid&amp;gt;&lt;br /&gt;&amp;lt;artifactid&amp;gt;maven-surefire-report-plugin&amp;lt;/artifactid&amp;gt;&lt;br /&gt;&amp;lt;version&amp;gt;2.4.3&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;lt;showsuccess&amp;gt;true&amp;lt;/showsuccess&amp;gt;&lt;br /&gt;&amp;lt;reportsdirectories&amp;gt;&lt;br /&gt;  &amp;lt;param&amp;gt;target/junit4osgi-reports&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;lt;/reportsdirectories&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&amp;lt;/plugins&amp;gt;&lt;br /&gt;&amp;lt;/reporting&amp;gt;&lt;br /&gt;&lt;/pre&gt;This snippet configures the maven-surefire-report-plugin to collect results from the ‘&lt;span style="font-style: italic;"&gt;target/junit4osgi-reports&lt;/span&gt;’ directory.&lt;br /&gt;Then execute the plugin with the following command:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;mvn org.apache.maven.plugins:maven-surefire-report-plugin:2.4.3:report&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This command generates the web page with test results in ‘target/site’. This &lt;a href="http://people.apache.org/%7Eclement/blog/site/surefire-report.html"&gt;page&lt;/a&gt;  shows an example of page generated with this command.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Plug-in design&lt;/span&gt;&lt;br /&gt;The plug-in is quiet simple, it just starts an embedded Felix with a special activator installing and starting the &lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt; framework and specified bundles.&lt;br /&gt;&lt;br /&gt;Then, before executing test, the plug-in waits for “&lt;span style="font-style: italic;"&gt;stability&lt;/span&gt;”. Indeed, as bundle activation can be asynchronous, the plug-in need to wait that the configuration is stable. Stability is obtained when all bundles are activated, and no new services appear or disappear on a 500 ms period. If after several second the stability cannot be reached, the plug-in stops.&lt;br /&gt;&lt;br /&gt;Once the stability is reached, the junit4ogsi runner service is used to execute tests. Then results are collected and reports are generated.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;This post has presented a front-end automating the execution of &lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt; tests. Now it is possible to integrate OSGi application tests in a build process. The presented maven plugin provides following features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;An easy integration in a Maven-based build process&lt;/li&gt;&lt;li&gt;A good flexibility allowing reproducing production execution environments to test the application&lt;/li&gt;&lt;li&gt;Test result output is the same as surefire&lt;/li&gt;&lt;li&gt;Is able to generate Surefire-like reports&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-2899586091374975445?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/2899586091374975445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=2899586091374975445' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2899586091374975445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2899586091374975445'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2008/11/maven-junit4osgi-plugin.html' title='maven-junit4osgi-plugin'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-2158454914799638440</id><published>2008-11-02T18:33:00.006+01:00</published><updated>2008-11-06T18:25:46.272+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='en'/><category scheme='http://www.blogger.com/atom/ns#' term='tests'/><title type='text'>Lessons learned from iPOJO testing process</title><content type='html'>Recently, we ask me several times if iPOJO is tied to the Felix runtime (i.e. works only on Felix). So, the answer is simple:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;iPOJO relies only on the OSGi 4.1 specification, &lt;/span&gt; &lt;span style="font-weight: bold;"&gt;and so can work on any compliant implementation.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This post just explains how iPOJO is currently tested, and reflexion on OSGi application testing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Test, Test and Test...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, why testing?&lt;br /&gt;Just because I'm very clumsy, and I can't guaranty that a patch don't have side effects broking a features. So, my tests aims to check that features still works and that I don't broke everything... That's why I developed &lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt; at the same times as &lt;span style="font-style: italic;"&gt;iPOJO&lt;/span&gt;. Before this improvement, testing iPOJO takes something like a working day! (now, it's close to 3 minutes...)&lt;br /&gt;&lt;br /&gt;The iPOJO testing process weekly executed on three different OSGi implementations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://felix.apache.org/"&gt;Apache Felix&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.eclipse.org/equinox/"&gt;Eclipse Equinox&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.knopflerfish.org/kf2.html"&gt;Knopflerfish 2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;"Tested" means that the test suite is executed &lt;span style="font-weight: bold;"&gt;successfully&lt;/span&gt; on each implementation. This is done thanks to the &lt;a href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html"&gt;&lt;span style="font-style: italic;"&gt;junit4OSGi&lt;/span&gt;&lt;/a&gt; framework compatible with those implementations.&lt;br /&gt;The test suite is also executed on different VMs such as Mika, JamVM and JRockit. Those tests are twofold:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Checks that the iPOJO framework can be executed on different VMs.&lt;/li&gt;&lt;li&gt;Checks that the iPOJO manipulation process generates consistent bytecode. &lt;/li&gt;&lt;/ol&gt;The second point is important, as the VMs are more or less tolerant to some mistakes ☺.  Specially, Sun VMs are very tolerant!&lt;br /&gt;&lt;br /&gt;So, let’s back to the testing process. The iPOJO test suite checks the most part of the iPOJO’s features.  The iPOJO trunk contains a lot of test cases executed with the junit4osgi framework. Executing the test suite is quite simple: launch the OSGi implementation, launch the junit4osgi framework, deploy tests and finally use a front end (command line, GUI) to run tests.&lt;br /&gt;&lt;br /&gt;Simple, isn’t it? However, during the development of the test suite, several issues appears:&lt;br /&gt;-    Handling asynchronous interactions&lt;br /&gt;-    Integrating test in the building process&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Issues to test OSGi Applications&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Testing services and their behavior is really easy with junit4OSGi. However, it becomes trickier when services realize asynchronous actions (i.e. actions are executed in a different thread and so not sequentially).&lt;br /&gt;&lt;br /&gt;OSGi proposes an execution platform where a lot of actions are made asynchronously. Testing this kind of interaction is difficult, and generally requires &lt;span style="font-style: italic;"&gt;magic waiting time&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;For example, imagine a test pushing a configuration inside the configuration admin. The test creates a new configuration, pushes it to the configuration to the configuration admin, and checks that the configuration is correctly applied. However, the configuration admin applies the configuration in another thread. So the test must wait before checking that the configuration is correctly applied. Waiting is admitted, but how much time? Choosing a default time is rarely is good choice because it greatly depends on your configuration… Setting a long duration implies a long executing time…&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_fTY6niaFaAc/SRMm2nRYeaI/AAAAAAAAD58/TOGn6Ak9Swc/s1600-h/ca1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 204px;" src="http://4.bp.blogspot.com/_fTY6niaFaAc/SRMm2nRYeaI/AAAAAAAAD58/TOGn6Ak9Swc/s320/ca1.png" alt="" id="BLOGGER_PHOTO_ID_5265595109022923170" border="0" /&gt;&lt;/a&gt;So, you can argue that the Configuration Admin provide mechanisms notifying when configurations are correctly processed. That’s great, and the OSGi specification defines similar mechanisms for the most part of asynchronous interactions. So it should be possible to wait for this notification (or eventually throws a timeout).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_fTY6niaFaAc/SQ3nmDHbq3I/AAAAAAAAD5s/vP-B7xnVYac/s1600-h/ca2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 222px;" src="http://3.bp.blogspot.com/_fTY6niaFaAc/SQ3nmDHbq3I/AAAAAAAAD5s/vP-B7xnVYac/s320/ca2.png" alt="" id="BLOGGER_PHOTO_ID_5264118180323502962" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;However, if the ManagedService or the ManagedServiceFactory to update is not available, the notification is fired immediately, and is no more fired once the service arrives (at least on the Felix Configuration Admin). So, in this case you have to wait for an arbitrary time ☹. I’m looking for a better solution, but right now it still obscures to me how to handle those interactions cleanly.&lt;br /&gt;&lt;br /&gt;The second issue with junit4osgi is very different. Executing tests are easy but I’m very (very) lazy. So, integrating those tests inside my build process could be great. An Ant task or a Maven plug-in could execute those tests automatically and react according to the results (if a failure or an error is detected, the build process fails).  This automation can be easily implemented. It just requires starting an OSGi implementation, deploying the junit4osgi framework, starting required bundles as well as bundles containing tests and launching the test execution. It exist testing framework doing this, but they are generally usable only inside the build process and so lacks of flexibility. It must be possible to execute test manually on non-standard configurations.  I’m going to implement a simple Ant task doing this. I’ll keep you posted…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-2158454914799638440?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/2158454914799638440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=2158454914799638440' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2158454914799638440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2158454914799638440'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2008/11/lessons-learned-from-ipojo-testing.html' title='Lessons learned from iPOJO testing process'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_fTY6niaFaAc/SRMm2nRYeaI/AAAAAAAAD58/TOGn6Ak9Swc/s72-c/ca1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-2037021806764536591</id><published>2008-10-25T13:15:00.002+02:00</published><updated>2008-10-25T13:18:28.908+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='en'/><title type='text'>iPOJO 1.0.0 and the future</title><content type='html'>I recently released the version 1.0.0 of the iPOJO framework. This release is a major milestone for iPOJO.&lt;br /&gt;&lt;br /&gt;iPOJO was created two years ago in the continuation of the Service Binder effort. The initial goal was to provide an easy way to create dynamic service-based applications on the top of OSGi without losing the OSGi philosophy (small, universal middleware).&lt;br /&gt;At the same time, I was involved in several projects where I realized that iPOJO must focus on different goals:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Must be simple… (Avoids redundancies, provides annotations)&lt;/li&gt;&lt;li&gt;Must be extensible to tackle specific requirements&lt;/li&gt;&lt;li&gt;Must provide a way to design applications&lt;/li&gt;&lt;/ul&gt;The first requirement comes from the OSGi development model. OSGi is very powerful, but the learning curve is slow and long. A lot of mechanisms (mostly about class loading and threads) must be understood. Hiding or simplifying those mechanisms was a stringent requirement.&lt;br /&gt;&lt;br /&gt;The first project using iPOJO was the design and the implementation of a residential gateway. However, we quickly understood that developing such kind of application requires some specific technical services such as a MOM allowing event-based interactions, a scheduler (i.e. Cron) to automate periodic task triggering, a way to administrate applications remotely… Providing such technical services is not too difficult. However, automating the interaction with those technical services was more challenging. From this observation, we decide to provide an extension mechanism allowing adding such kind of features without modifying the core of the project. So, iPOJO can be small as well as providing a lot of functionalities.&lt;br /&gt;&lt;br /&gt;Finally, we realize that we need a way to design applications. Traditional ways to design applications are somewhat limited. Generally they are limited to static applications (with no possible evolution at runtime) and the architecture description is lost just after that the application is deployed.  After a long work with Richard S. Hall, we propose and implement a new way to design applications on the top of OSGi. iPOJO composite allows isolating services, support dynamism … This is the most innovative part of the iPOJO project.&lt;br /&gt;The &lt;a href="http://ipojo.org"&gt;iPOJO 1.0.0 release&lt;/a&gt; is the result of these two years of development, research, interrogations and experimentations.  The iPOJO framework is composed by:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A core system providing basics functionalities (requiring/providing services, lifecycle, instance introspections…)&lt;/li&gt;&lt;li&gt;A full integration with the Configuration Admin&lt;/li&gt;&lt;li&gt;A way to design and execute dynamic applications&lt;/li&gt;&lt;li&gt;Several external handler extending core capabilities with JMX administration, Event Admin interactions, Temporal service dependency, whiteboard and extender patterns …&lt;/li&gt;&lt;/ul&gt;The future of iPOJO is also exciting. With the support of my ‘future former’ group, extensions such as distribution and deployment are under development. The distribution framework allows iPOJO instances to interact with remote services (using any protocol) and can be exposed remotely. The deployment support computes OBR descriptions from metadata providing features easing the deployment. Improvements such as providing a control and creation API are also investigated.  The future version will see the arriving of new ‘&lt;span style="font-style: italic;"&gt;handlers&lt;/span&gt;’ handling persistence and scheduling as well as a better integration with the &lt;a href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html"&gt;&lt;span style="font-style: italic;"&gt;junit4osgi&lt;/span&gt;&lt;/a&gt; framework.&lt;br /&gt;&lt;br /&gt;All those stuffs are really promising… Isn’t it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-2037021806764536591?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/2037021806764536591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=2037021806764536591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2037021806764536591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/2037021806764536591'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2008/10/ipojo-100-and-future.html' title='iPOJO 1.0.0 and the future'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3096964353090017094.post-5871008223385145036</id><published>2008-10-21T15:38:00.024+02:00</published><updated>2008-11-11T18:20:32.597+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipojo'/><category scheme='http://www.blogger.com/atom/ns#' term='en'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>iPOJO on Android</title><content type='html'>Android is the Google OS for mobile phone (and the future GPhone). Android provides a Java-like virtual machine: Dalvik.&lt;br /&gt;&lt;br /&gt;So, why not trying to execute an iPOJO-based application on the top of Android?&lt;br /&gt;The idea was to embed an OSGi/iPOJO framework on Android and then to deploy an application on the top of the framework.&lt;br /&gt;&lt;br /&gt;You can download the application in two parts:&lt;br /&gt;the Android application embedding Felix/iPOJO : &lt;a href="http://people.apache.org/%7Eclement/ipojo/tutorials/android/ipojo_on_android.zip"&gt;here&lt;br /&gt;&lt;/a&gt;the SpellChecker application : &lt;a href="http://people.apache.org/%7Eclement/ipojo/tutorials/android/spellchecker_on_android.zip"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The application is designed as follow:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Android application creates and starts a OSGI/iPOJO framework (Felix + iPOJO + FileInstall)&lt;/li&gt;&lt;li&gt; The Android application tracks a ViewFactory service. This service is used to display the application GUI (the service allows creating the GUI main component).&lt;/li&gt;&lt;li&gt;The SpellChecker application (10 minutes tutorial) is deployed on OSGi, and use iPOJO. The only difference with the one form the 10 minutes tutorial is the GUI that uses Android HMI component (rather than Swing) &lt;/li&gt;&lt;/ul&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_fTY6niaFaAc/SP3ujpDfLfI/AAAAAAAAD5M/19iUVHEIy2Y/s1600-h/app.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_fTY6niaFaAc/SP3ujpDfLfI/AAAAAAAAD5M/19iUVHEIy2Y/s320/app.png" alt="" id="BLOGGER_PHOTO_ID_5259622235921919474" border="0" /&gt;&lt;/a&gt;SpellChecker application bundles are deployed thanks to FileInstall. A specific folder is monitored in order to install/update/uninstall jar files contained in this folder.&lt;br /&gt;&lt;h2&gt;&lt;br /&gt;&lt;/h2&gt;&lt;h2&gt;Embedding Felix and iPOJO inside an Android Application&lt;/h2&gt;&lt;br /&gt;First, we need to create an Android application. This application creates a new Felix when the application is instantiated:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public synchronized void onCreate(Bundle icicle) {&lt;br /&gt;super.onCreate(icicle);&lt;br /&gt;setContentView(R.layout.main);&lt;br /&gt;PrintStream out = new PrintStream(new OutputStream(){&lt;br /&gt;ByteArrayOutputStream output = new ByteArrayOutputStream();&lt;br /&gt;@Override&lt;br /&gt;public void write(int oneByte) throws IOException {&lt;br /&gt;  output.write(oneByte);&lt;br /&gt;  if (oneByte == '\n') {&lt;br /&gt;    Log.v("out", new String(output.toByteArray()));&lt;br /&gt;    output = new ByteArrayOutputStream();&lt;br /&gt;  }&lt;br /&gt;}});&lt;br /&gt;System.setErr(out);&lt;br /&gt;System.setOut(out);&lt;br /&gt;m_configMap = new StringMap(false);&lt;br /&gt;m_configMap.put(FelixConstants.LOG_LEVEL_PROP,String.valueOf(Logger.LOG_DEBUG));&lt;br /&gt;m_configMap.put(DirectoryWatcher.DEBUG, "1");&lt;br /&gt;// Configure the Felix instance to be embedded.&lt;br /&gt;m_configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP, "true");&lt;br /&gt;File bundles = new File(FELIX_BUNDLES_DIR);&lt;br /&gt;if (!bundles.exists()) {&lt;br /&gt; if (!bundles.mkdirs()) {&lt;br /&gt;    throw new IllegalStateException("Unable to create bundles dir");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;m_configMap.put(DirectoryWatcher.DIR, bundles.getAbsolutePath());&lt;br /&gt;// Add core OSGi packages to be exported from the class path&lt;br /&gt;// via the system bundle.&lt;br /&gt;m_configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES, ANDROID_FRAMEWORK_PACKAGES);&lt;br /&gt;// Explicitly specify the directory to use for caching bundles.&lt;br /&gt;try {&lt;br /&gt; m_cache = File.createTempFile("felix-cache", null);&lt;br /&gt;} catch (IOException ex) {&lt;br /&gt; throw new IllegalStateException(ex);&lt;br /&gt;}&lt;br /&gt;m_cache.delete();&lt;br /&gt;m_cache.mkdirs();&lt;br /&gt;m_configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP, m_cache.getAbsolutePath());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When the application starts, the Felix Framework is started with two Activators :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;one installing bundles from resources&lt;/li&gt;&lt;li&gt;one installing bundles from a folder (FileInstall)&lt;/li&gt;&lt;/ul&gt;Then a service tracker is used to track arrivals and departures of the ViewFactory (provided by the SpellChecker GUI).&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public synchronized void onStart() {&lt;br /&gt;super.onStart();&lt;br /&gt;setContentView(new View(this));&lt;br /&gt;Resources res = getResources();&lt;br /&gt;try {&lt;br /&gt; List&amp;lt;BundleActivator&amp;gt; activators = new ArrayList&amp;lt;BundleActivator&amp;gt;();&lt;br /&gt;&lt;br /&gt; // Plugs the bundle installer (install bundle from application resources)&lt;br /&gt; activators.add(new Installer(res));&lt;br /&gt; // Plugs the FileInstall activator&lt;br /&gt; activators.add(new FileInstall());&lt;br /&gt;&lt;br /&gt; m_felix = new Felix(m_configMap, activators);&lt;br /&gt; m_felix.start();&lt;br /&gt;} catch (BundleException ex) {&lt;br /&gt; throw new IllegalStateException(ex);&lt;br /&gt;}&lt;br /&gt;try {&lt;br /&gt; m_tracker = new ServiceTracker(m_felix.getBundleContext(),&lt;br /&gt;  m_felix.getBundleContext().createFilter("(" + Constants.OBJECTCLASS&lt;br /&gt;      + "=" + ViewFactory.class.getName() + ")"),&lt;br /&gt;      new ServiceTrackerCustomizer() {&lt;br /&gt;&lt;br /&gt;      @Override&lt;br /&gt;      public Object addingService(ServiceReference ref) {&lt;br /&gt;          System.out.println("======= Service found !");&lt;br /&gt;          final ViewFactory fac =&lt;br /&gt;             (ViewFactory) m_felix.getBundleContext().getService(ref);&lt;br /&gt;          if (fac != null) {&lt;br /&gt;              runOnUiThread(new Runnable() {&lt;br /&gt;                   public void run() {&lt;br /&gt;                      setContentView(fac.create(ApacheFelix.this));&lt;br /&gt;                  }&lt;br /&gt;              });&lt;br /&gt;          }&lt;br /&gt;          return fac;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      @Override&lt;br /&gt;      public void modifiedService(ServiceReference ref,&lt;br /&gt;              Object service) {&lt;br /&gt;          removedService(ref, service);&lt;br /&gt;          addingService(ref);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      @Override&lt;br /&gt;      public void removedService(ServiceReference ref,&lt;br /&gt;              Object service) {&lt;br /&gt;          m_felix.getBundleContext().ungetService(ref);&lt;br /&gt;          runOnUiThread(new Runnable() {&lt;br /&gt;              public void run() {&lt;br /&gt;                  setContentView(new View(ApacheFelix.this));&lt;br /&gt;              }&lt;br /&gt;          });&lt;br /&gt;      }});&lt;br /&gt;m_tracker.open();&lt;br /&gt;} catch (InvalidSyntaxException e) {&lt;br /&gt; e.printStackTrace();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that the iPOJO bundle is deployed from application resource. The bundle was “dexed” and placed in the res/raw folder of the application project. Then, you can load the bundle with:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void start(BundleContext arg0) throws Exception {&lt;br /&gt;&lt;br /&gt;InputStream is = res.openRawResource(R.raw.ipojo);&lt;br /&gt;&lt;br /&gt;Bundle bundle = arg0.installBundle(IPOJO_HTTP_PATH, is);&lt;br /&gt;bundle.start();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Before the be installed, the application must be exported in a .apk file.&lt;br /&gt;SpellChecker application&lt;br /&gt;The application is basically the same than the one form the 10 minutes tutorial. There are two differences:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Bundles are “dexed”&lt;/li&gt;&lt;li&gt;The GUI bundle is implemented with Android GUI components&lt;/li&gt;&lt;/ul&gt;Another difference is about the optionality of the dependency on SpellChecker service. This dependency is now optional, and use two bind/unbind methods:&lt;br /&gt;&lt;pre name="code" class="java"&gt;public synchronized void bindSpellChecker(SpellChecker sp) {&lt;br /&gt;checker = sp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if (activity != null) {&lt;br /&gt;activity.runOnUiThread(new Runnable() {&lt;br /&gt;public void run() {&lt;br /&gt;  // Enable button&lt;br /&gt;  m_button.setEnabled(true);&lt;br /&gt;  m_result.setText("Enter words, and click on 'check'");&lt;br /&gt;  m_main.invalidate();&lt;br /&gt;  System.out&lt;br /&gt;          .println("==&gt; Spell checker GUI receives&lt;br /&gt;           a new spell checker ...");&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public synchronized void unbindSpellChecker(SpellChecker sp) {&lt;br /&gt;checker = null;&lt;br /&gt;if (activity != null) {&lt;br /&gt;activity.runOnUiThread(new Runnable() {&lt;br /&gt;public void run() {&lt;br /&gt;  // Enable button&lt;br /&gt;  m_button.setEnabled(false);&lt;br /&gt;  m_result.setText("No Spellchecker available");&lt;br /&gt;  m_main.invalidate();&lt;br /&gt;  System.out&lt;br /&gt;          .println("=====&gt; Spell checker GUI was&lt;br /&gt;           unbind from the spell checker");&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that GUI modifications &lt;span style="font-weight: bold;"&gt;MUST&lt;/span&gt; be done in the UI Thread.&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3&gt;Starting the emulator&lt;/h3&gt;&lt;br /&gt;The application uses a SD card storage. So creates an SDCard iso:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;br /&gt;mksdcard size filename&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then, launch the emulator (emulator must be accessible from your path)  with:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;br /&gt;emulator -shell -sdcard dev/android/sdcard1.iso&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The emulator starts. When the shell is ready, change the permission access on  /data/dalvik-cache:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;br /&gt;chmod 777 /data/dalvik-cache&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These permissions are needed to correctly load bundles.&lt;br /&gt;&lt;h3&gt;Installing the application&lt;/h3&gt;&lt;br /&gt;To install the application (the .apk file), I use the Eclipse plugin (the apk file can be unsigned) or with the adb command (the apk file must be signed).&lt;br /&gt;Once signed, you can deploy your application with:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;br /&gt;adb install application.apk&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once installed, the application is available in the Android emulator menu&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_fTY6niaFaAc/SP3xZArxANI/AAAAAAAAD5U/rCrXY9uPvdM/s1600-h/menu.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://1.bp.blogspot.com/_fTY6niaFaAc/SP3xZArxANI/AAAAAAAAD5U/rCrXY9uPvdM/s320/menu.png" alt="" id="BLOGGER_PHOTO_ID_5259625351821197522" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;If you launch the application, a black screen appears … The Spellchecker application is not deployed!&lt;br /&gt;So, to deploy the application, the bundles files must be placed in the /data/felix/bundles folder.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;adb push SpellCheckGui\ for\ Android.jar /data/felix/bundles/SpellcheckGui.jar gui.jar&lt;br /&gt;cd bundles&lt;br /&gt;adb push spell.services.jar /data/felix/bundles/spell.services.jar&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_fTY6niaFaAc/SP3x8XqzN7I/AAAAAAAAD5c/A-5wofIcCkM/s1600-h/spell-ok.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_fTY6niaFaAc/SP3x8XqzN7I/AAAAAAAAD5c/A-5wofIcCkM/s320/spell-ok.png" alt="" id="BLOGGER_PHOTO_ID_5259625959286585266" border="0" /&gt;&lt;/a&gt;If you launch the application, the GUI appears, but you can’t use the check button. No spell checker services are available. Push the others jars in the same folder.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;adb push spell.checker.jar \&lt;br /&gt;/data/felix/bundles/spell.checker.jar&lt;br /&gt;adb push spell.english.jar \&lt;br /&gt;/data/felix/bundles/spell.english.jar&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once done, the check button becomes available. If you remove a the English dictionary, the check button becomes disabled:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px;"&gt;adb shell rm /data/felix/bundles/spell.english.jar&lt;br /&gt;adb push spell.english.jar /data/felix/bundles/spell.english.jar&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;This very simple application has shown that it is possible to create dynamic applications on the top of Android with OSGi and iPOJO. It sounds really promising …&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;References&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.luminis.nl/roller/luminis/entry/osgi_on_google_android_using"&gt;http://blog.luminis.nl/roller/luminis/entry/osgi_on_google_android_using&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-and-google-android.html"&gt;http://felix.apache.org/site/apache-felix-and-google-android.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://felix.apache.org/site/presentations.data/OSGi%20on%20Google%20Android%20using%20Apache%20Felix.pdf"&gt;http://felix.apache.org/site/presentations.data/OSGi%20on%20Google%20Android%20using%20Apache%20Felix.pdf&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3096964353090017094-5871008223385145036?l=ipojo-dark-side.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ipojo-dark-side.blogspot.com/feeds/5871008223385145036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3096964353090017094&amp;postID=5871008223385145036' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/5871008223385145036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3096964353090017094/posts/default/5871008223385145036'/><link rel='alternate' type='text/html' href='http://ipojo-dark-side.blogspot.com/2008/10/ipojo-on-android.html' title='iPOJO on Android'/><author><name>Clement</name><uri>http://www.blogger.com/profile/14164928860731312792</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_fTY6niaFaAc/SP3ujpDfLfI/AAAAAAAAD5M/19iUVHEIy2Y/s72-c/app.png' height='72' width='72'/><thr:total>10</thr:total></entry></feed>
