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

<channel>
	<title>Luminis Software Development &#187; Uncategorized</title>
	<atom:link href="http://lsd.luminis.nl/en/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://lsd.luminis.nl</link>
	<description></description>
	<lastBuildDate>Wed, 18 Aug 2010 10:10:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PhoneGap, een alternatief voor native mobiele applicaties</title>
		<link>http://lsd.luminis.nl/en/phonegap/</link>
		<comments>http://lsd.luminis.nl/en/phonegap/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 06:55:32 +0000</pubDate>
		<dc:creator>Erik Sanders</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[mobility]]></category>
		<category><![CDATA[Google Android]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[News Item]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://lsd.luminis.nl/?p=1005</guid>
		<description><![CDATA[PhoneGap, een alternatief voor native mobiele applicaties
PhoneGap is een interessante open source alternatief voor het schrijven van native applicaties voor elk (mobiel) platform dat er is. In het kort komt het erop neer dat PhoneGap zorgt dat je een HTML applicatie met javascript.  De specifiek API, zoals location, contact, e.d. worden afgeschermd door een standaard API [...]]]></description>
			<content:encoded><![CDATA[<h1>PhoneGap, een alternatief voor native mobiele applicaties</h1>
<p>PhoneGap is een interessante open source alternatief voor het schrijven van native applicaties voor elk (mobiel) platform dat er is. In het kort komt het erop neer dat PhoneGap zorgt dat je een HTML applicatie met javascript.  De specifiek API, zoals location, contact, e.d. worden afgeschermd door een standaard API van PhoneGap.</p>
<h3>iPhone</h3>
<p><span style="font-size: 13.3333px;">Voor de iPhone kan de HTML applicatie gewoon worden aangeboden via de appstore. Dit is dan ook direct de truc waardoor er voldoende rechten zijn om de hardware aan te spreken. Er zijn al vele applicatie geplaatst in de appstore (zie een selectie in<a href="http://www.phonegap.com/apps" target="_blank"> www.phonegap.com/apps</a>).  Er is tevens een <a href="http://phonegap.pbworks.com/Getting-Started-with-PhoneGap-(iPhone)" target="_blank">getting started</a> en er zijn  extra <a href="http://github.com/purplecabbage/PhoneGap-Plugins">plugins</a> beschikbaar</span></p>
<h3>Ondersteunde platformen</h3>
<p>Naast iPhone wordt zowel Android, Blackberry, Symbian, Palm, N900 en Windows Mobile. Ook Windows Mobile 7 is zodra dit uitkomt eenvoudig te ondersteunen en ze zullen ook geen blokkade opwerpen in het voordeel van silverlight. Interesante gedachte is natuurlijk ook de iets minder mobiele system met Linux, Windows MacOS hebben ook allemaal een browser.</p>
<table style="float:lefts" border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td></td>
<td>IPHONE</td>
<td>ANDROID</td>
<td>BLACKBERRY</td>
<td>SYMBIAN</td>
<td>PALM</td>
</tr>
<tr>
<td>GEO   LOCATION</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>VIBRATION</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>ACCELEROMETER</td>
<td>√</td>
<td>√</td>
<td>OS 4.7</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>SOUND</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>CONTACT   SUPPORT</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>N/A</td>
</tr>
</tbody>
</table>
<p>Voor meer informatie zie <a href="http://www.phonegap.com" target="_blank">www.phonegap.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/phonegap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Who writes my user stories</title>
		<link>http://lsd.luminis.nl/en/who-writes-my-user-stories/</link>
		<comments>http://lsd.luminis.nl/en/who-writes-my-user-stories/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 06:44:44 +0000</pubDate>
		<dc:creator>Albert Oudenampsen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[requirements]]></category>

		<guid isPermaLink="false">http://lsd.luminis.nl/?p=961</guid>
		<description><![CDATA[The user story is one of the useful initiatives that came out of the Agile movement. It expresses a very specific user need. Usually it&#8217;s written in just a few sentences in the language of the users. So any user and developer should be able to read a user story and immediately understand it.
User stories [...]]]></description>
			<content:encoded><![CDATA[<p>The user story is one of the useful initiatives that came out of the Agile movement. It expresses a very specific user need. Usually it&#8217;s written in just a few sentences in the language of the users. So any user and developer should be able to read a user story and immediately understand it.</p>
<p>User stories gained popularity after realizing that developers had to start working with users throughout the project to understand their needs. It certainly works better than letting a developer discuss the needs with a user, which tends to end after a few minutes in a &#8220;Yes, I get it! No worries, know what you need&#8221;, followed by a near endless code-and-fix cycles.</p>
<p>So user stories are great, but who writes them? Hmmm, users probably. After all it&#8217;s their story. Question is &#8220;can users write user stories&#8221;? The answer is simple: it depends….</p>
<p>Certainly some users can write user stories. Sysadmins can, helpdesk and application support too. But the &#8220;real&#8221; users, can they write user stories? I don&#8217;t know about that. When you leave the writing of user stories in the hands of the users that can write user stories you may end up with &#8220;unbalanced systems&#8221; like the ones in the famous what-if-airplanes picture. After all, you don&#8217;t build a system just to do application support or system admin (unless that is your business). You build systems to increase &#8220;business value&#8221; or whatever greater purpose and for that you need the &#8220;real&#8221; users. <br/><br />
<img src="http://lsd.luminis.nl/wp-content/uploads/2010/07/what_if_airplanes2.JPG" alt="what_if_airplanes" title="what_if_airplanes" width="825" height="540" class="alignleft size-full wp-image-966" />
</p>
<p>As stated before: &#8220;any user and developer should be able to read a user story and immediately understand it&#8221;. If it is that simple, it cannot be too hard to learn how to write a user story. </p>
<p>A user story consists of two parts:<br/><br />
-Just a few lines of text that describe the problem;<br/><br />
-A Test that serves as an example and that can be used to determine when a story is complete.<br/><br />
A simple template for this can be found here: <a href="http://cukes.info">cukes.info</a><br/><br />
All very simple, and I bet it is possible to make a training course with exercises were the stories and their tests just drip of the table….</p>
<p>Unfortunately, most systems we build nowadays are not that simple. Recently I explained user stories to a group of barristers who were asked to describe their new system. After the theoretical part it was time for some their first user story. Not some lab example a real life one.<br/><br />
Barrister: how do we start?<br/><br />
Me: just go over the things you do during the day and see where your new system system comes in<br/><br />
Barrister: I visit people with a legal document, hand it over, explain the implications and sometimes I give them advice or propose a solution. Then I make notes on their file. That&#8217;s it.<br/><br />
Me: Hmmm, that is too simple, there must be more&#8230;..<br/><br />
The discussion continued for quite some time and finally we found that the user story was about efficiency. In the morning they receive a pile of documents for that day, they order them by address, program their navigation system and they make their visits.</p>
<p>Or the cukes.info template:<br/><br />
<code>In order to make as many visits as possible during a day<br/><br />
As a barrister<br/><br />
I want to receive an daily workload optimized for traveling time and in such a way that I spend the least possible time in programming my navigation system.</code>
</p>
<p>Barrister: not in a million years I would have come up with this user story! And how do I write a test for this? Is the navigation system part of the whole system? And what if there are traffic jams or rush hours should that be in there too? And what about different makes of navigation systems?</p>
<p>My conclusion: help your users in writing user stories and certainly help them in writing test scenario&#8217;s. </p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/who-writes-my-user-stories/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FitNesse and OSGi</title>
		<link>http://lsd.luminis.nl/en/fitnesse-and-osgi/</link>
		<comments>http://lsd.luminis.nl/en/fitnesse-and-osgi/#comments</comments>
		<pubDate>Tue, 25 May 2010 19:59:38 +0000</pubDate>
		<dc:creator>Angelo van der Sijpt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[acceptance testing]]></category>
		<category><![CDATA[fitnesse]]></category>
		<category><![CDATA[modularity]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://lsd.luminis.nl/?p=901</guid>
		<description><![CDATA[(Nederlands) Recently, I built a demonstrator project connecting FitNesse and OSGi. We show how that can help your project, and how we did it.]]></description>
			<content:encoded><![CDATA[<p>As a demonstrator for a customer, I recently built a set of fixtures that allow <a href="http://www.fitnesse.org">FitNesse</a> acceptance tests to talk to an OSGi framework. <strong>This code is by no means production quality, but merely intended to show the concept and explain the challenges.</strong></p>
<p>I will not explain the details of the acceptance tests here, however, if there&#8217;s one point I would like to get across, it&#8217;s <em>your fixtures should be as narrow as possible</em> to easily accommodate for implementation changes. Study the different <code>UserAdmin</code> fixtures for more details. Also, I assume some familiarity with OSGi.</p>
<h2>FitNesse and OSGi. Why?</h2>
<p>Of course its fun, there is some real benefit to be gained here. While the industry well understands the need for unit- and integration testing, also in a modular context, it becomes more complex to create the necessary link between business and code. Yes, using a modular architecture we can behave in a more agile fashion, but all that agility is no good if the business doesn&#8217;t hop on the train, and explain well what it needs. FitNesse allows the business to explain its goals in business-lingo, while forcing the specification to be precise enough to be executable: if a concept cannot be explained by simple scenarios, something is wrong, but that&#8217;s a different story.</p>
<p>The modular nature of OSGi means that behavior of an application is more emergent than deterministic, making it harder to reason about its correctness: we can prove that our code and bundles are correct (unit tests), that everything works together as it should (integration tests), and that it looks right (user interface tests). However, proving that the business rules (which may well be one of those emergent properties) are handled correctly in a given setting, is another can of worms: we need to connect our acceptance tests to the OSGi framework.</p>
<h2>The big picture</h2>
<p><a href="http://lsd.luminis.nl/wp-content/uploads/2010/05/Screen-shot-2010-05-25-at-9.27.41-PM.png"><img src="http://lsd.luminis.nl/wp-content/uploads/2010/05/Screen-shot-2010-05-25-at-9.27.41-PM-300x146.png" alt="FitNesse and OSGi - overview" title="FitNesse and OSGi - overview" width="300" height="146" class="alignnone size-medium wp-image-903" /></a></p>
<p>The solution presented below uses a special &#8216;fixtures&#8217; bundle, which can be deployed along side other bundles in your framework. This bundles exposes an interface (in our case, through an <code>HTTPServlet</code>), which is used by a set of connectors, which in turn are used by FitNesse.</p>
<h2>The details</h2>
<p><a href="http://lsd.luminis.nl/wp-content/uploads/2010/05/2010_05_25_21_38_03.png"><img src="http://lsd.luminis.nl/wp-content/uploads/2010/05/2010_05_25_21_38_03-300x212.png" alt="FitNesse and OSGi - detailed" title="FitNesse and OSGi - detailed" width="300" height="212" class="alignnone size-medium wp-image-905" /></a></p>
<p>The ingredients are two parts connector code, one part boiler plate, and one part genuine OSGi-aware fixtures.</p>
<h3>The connectors</h3>
<p>Starting at the level closest to FitNesse, we find a set of fixtures that FitNesse can use. For us, these contain merely boiler plate code.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> removeUser<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    doRemoteCall<span style="color: #009900;">&#40;</span>buildRemoteCall<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UserAdmin&quot;</span>, name<span style="color: #009900;">&#41;</span>, <span style="color: #003399;">Void</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This code instructs our <code>RemoteInvoker</code> to do some call to the outside world. For more details, see <code>RemoteInvoker.java</code> in the <code>UserAdminRemoteFixtures</code> project.</p>
<h3>The fixture bundle</h3>
<p>Moving one step closer to our service, and into the OSGi framework, we find a <code>FixtureServlet</code>, whose task it is to receive calls from the <code>RemoteInvoker</code>, and turn them into actual method calls on the fixtures.</p>
<p>The fixtures, then, are almost regular OSGi aware objects. I chose to use the <a href="http://felix.apache.org/site/apache-felix-dependency-manager.html">Apache Felix Dependency Manager</a> for the dependency management of the fixtures. So, for our UserAdmin fixture, the dependencies are</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">manager.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>createService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">setInterface</span><span style="color: #009900;">&#40;</span>UserAdminListener.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">setImplementation</span><span style="color: #009900;">&#40;</span>userAdmin<span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>createServiceDependency<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        .<span style="color: #006633;">setService</span><span style="color: #009900;">&#40;</span>UserAdmin.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>
        .<span style="color: #006633;">setRequired</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Here, we state that we have some instance of a fixture <code>userAdmin</code> that registers itself as a <code>UserAdminListener</code> and needs a <code>UserAdmin</code>. How straightforward is that?
</p>
<p>The final step takes us to the actual fixture,</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> UserAdminFixture <span style="color: #000000; font-weight: bold;">implements</span> UserAdminListener <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">volatile</span> UserAdmin m_userAdmin<span style="color: #339933;">;</span>
...
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> addUser<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		m_usersCreatedInLastCall <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		m_userAdmin.<span style="color: #006633;">createRole</span><span style="color: #009900;">&#40;</span>name, Role.<span style="color: #006633;">USER</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
...
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>which is just another component using a the <code>UserAdmin</code> service.
</p>
<h2>Putting it all together</h2>
<p>All we now need to do is deploy the fixture bundle in our project, and instruct FitNesse to use the remote connector. The zip file at the bottom of this post contains two shell scripts to do exactly that.</p>
<h2>Future work</h2>
<p>As I stated at the top of this story, this is by no means production quality code, but the concepts stand as they are. Given the way FitNesse works, the connectors do not need much extra work, perhaps support for collections. However, we could use</p>
<ul>
<li>a way to reduce the boiler plate code,</li>
<li>a way to ensure that that both side of the fixtures use the same function naming, and</li>
<li>better integration, for instance by only firing up a framework once a FitNesse suite is started.</li>
</ul>
<h2>Let&#8217;s play with it!</h2>
<p>I have built a <a href='http://lsd.luminis.nl/wp-content/uploads/2010/05/FitnesseAndOSGi.zip'>zip file</a> containing everything you need to get started, including a set of scenarios that can run with both a homebrew implementation of a User Admin, and the actual <a href="http://felix.apache.org">Apache Felix User Admin</a>. A Readme gives you more information on getting it all up and running.</p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/fitnesse-and-osgi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Meld je nu aan voor de AgileMDD kennissessie op 30 maart</title>
		<link>http://lsd.luminis.nl/en/meld-je-nu-aan-voor-de-agilemdd-kennissessie-op-30-maart/</link>
		<comments>http://lsd.luminis.nl/en/meld-je-nu-aan-voor-de-agilemdd-kennissessie-op-30-maart/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 09:56:03 +0000</pubDate>
		<dc:creator>Richard van der Laan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AgileMDD]]></category>
		<category><![CDATA[dsl]]></category>
		<category><![CDATA[mda]]></category>
		<category><![CDATA[mdd]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[uml]]></category>

		<guid isPermaLink="false">http://lsd.luminis.nl/?p=672</guid>
		<description><![CDATA[(Nederlands) Luminis Software Development en ArchitecIT nodigen je graag uit voor een kennissessie over model-driven development. We laten deze avond graag zien waarom modellen steeds belangrijker worden en hoe je er succesvol mee kunt zijn. De hele kennissessie zal in het teken staan van praktijkervaringen.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agilemdd.nl"></a><a href="http://www.agilemdd.nl"><img class="alignleft size-full wp-image-509" title="agilemdd_logo" src="http://lsd.luminis.nl/wp-content/uploads/2009/09/agilemdd_logo.png" alt="agilemdd_logo" width="141" height="45" /></a><br />
<strong> </strong><br />
<strong> </strong><br />
<strong> </strong><br />
Luminis Software Development en ArchitecIT nodigen je graag uit voor een kennissessie over model-driven development.</p>
<p>We laten deze avond graag zien waarom modellen steeds belangrijker worden en hoe je er succesvol mee kunt zijn. De hele kennissessie zal in het teken staan van praktijkervaringen. </p>
<p>Aan de hand van vijf verschillende thema&#8217;s delen sprekers van diverse organisaties hun ervaringen met MDD in de praktijk: <b>Thales Hengelo</b>, <b>Ministerie van Defensie</b>, <b>ArchitecIT</b>, <b>Delphino Consultancy</b> en <b>luminis</b>.</p>
<p>In onze visie is het noodzakelijk om de ontwikkelkracht slimmer in te zetten, niet in de laatste plaats door de enorme toename van complexiteit in softwareintensieve systemen. In de praktijk zijn is er nog veel communicatie (overdrachtsmomenten) en bestaan de meeste ontwikkeltaken uit veel handwerk. Op basis van een pragmatische en doelgerichte aanpak kunnen ontwikkeltaken snel worden geautomatiseerd en kan de onderlinge communicatie worden verbeterd.</p>
<p><b>Datum:</b> dinsdag 30 maart van 16:45 tot 20:00 uur<br />
<b>Locatie:</b> IJsselburcht 3, 6825 BS, Arnhem<br />
<b>Voor wie:</b> Architecten, ICT Managers en belangstellenden<br />
<b>Aanmelden:</b> U kunt zich aanmelden per email door contact op te nemen met <a href="mailto:inge.dokter@luminis.nl?SUBJECT=Aanmelding%20MDD%20Kennissessie">Inge Dokter</a></p>
<p><b>Het programma:</p>
<p>16:45 Opening in de grote zaal<br />
17:00 Agile MDD: huidige trends en ontwikkelingen (Tony Sloos, Richard van der Laan)<br />
17:30 MDA in realtime heterogene systemen (Rene van Hees, Alexander Broekhuis)<br />
18:00 Lopend buffet<br />
18:30 Microsoft DSL Toolkit in de praktijk (Gerrit Jan Timmermans, Erik Sanders)<br />
19:00 MDD en software architectuur (Angelo Hulshout)<br />
19:30 MDD kansen en risico&#8217;s (Andriy Levytskyy)<br />
20:00 Afsluiting met borrel<br />
</b><br />
Graag ontvangen we je aanmelding zo snel mogelijk, maar in iedergeval voor <b><u>12 maart</u></b>. Aan deelname zijn <b><u>geen kosten</u></b> verbonden.<br />
Je kan je aanmelding sturen naar Inge Dokter (<a href="mailto:inge.dokter@luminis.nl?SUBJECT=Aanmelding%20MDD%20Kennissessie">inge.dokter@luminis.nl</a>)</p>
<p>We hopen je te zien op dinsdag 30 maart!</p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/meld-je-nu-aan-voor-de-agilemdd-kennissessie-op-30-maart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Online video: Beyond OSGi software architecture</title>
		<link>http://lsd.luminis.nl/en/online-video-beyond-osgi-software-architecture/</link>
		<comments>http://lsd.luminis.nl/en/online-video-beyond-osgi-software-architecture/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 15:11:53 +0000</pubDate>
		<dc:creator>Richard van der Laan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[Apache Felix]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[lean]]></category>
		<category><![CDATA[nljug]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[Software architecture]]></category>

		<guid isPermaLink="false">http://lsd.luminis.nl/?p=601</guid>
		<description><![CDATA[(Nederlands) Op 11 november 2009 gaf Marcel Offermans samen met Jeroen van Grondelle (Be Informed) een duo presentatie over "Beyond OSGi software architecture". De video van deze presentatie is inmiddels online beschikbaar.]]></description>
			<content:encoded><![CDATA[<p>Op 11 november 2009 gaf Marcel Offermans samen met Jeroen van Grondelle (Be Informed) een duo presentatie over &#8220;Beyond OSGi software architecture&#8221;. De video van deze presentatie is inmiddels online beschikbaar. De gehele presentatie van 50 minuten kan je <a href="http://lsd.luminis.nl/wp-content/uploads/videos/Beyond%20OSGi%20software%20architecture.mp4">hier</a> downloaden. Maar de eerste tien minuten zijn hieronder gelijk online te bekijken.</p>
<p><!-- Smart Youtube --><span class="youtube"><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/vwJD0mhgnmU&amp;rel=1&amp;color1=e1600f&amp;color2=febd01&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;ap=%2526fmt%3D18" /><param name="allowFullScreen" value="true" /><embed wmode="transparent" src="http://www.youtube.com/v/vwJD0mhgnmU&amp;rel=1&amp;color1=e1600f&amp;color2=febd01&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;ap=%2526fmt%3D18" type="application/x-shockwave-flash" allowfullscreen="true" width="560" height="340" ></embed><param name="wmode" value="transparent" /></object></span></p>
<p>OSGi is niet meer weg te denken uit het Enterprise Java domein. Dit lightweight framework krijgt al een aantal jaren flinke aandacht en is met name bekend om z’n modulaire applicaties op basis van bundles. Minder bekend is het services model, waarbij applicaties worden ontwikkeld op basis van service interfaces en van elkaar ontkoppelde implementaties (POJO&#8217;s) van die interfaces. Krachtige eigenschappen van dit model zijn:</p>
<ul>
<li>complexiteitsreductie door stricte scheiding van services;</li>
<li>declaratieve services en dependency management (IoC);</li>
<li>aspect oriëntatie op basis van stub services;</li>
<li>security model.</li>
</ul>
<p>Lean software is een nieuwe manier om enterprise applicaties te bouwen op basis van OSGi, die ook goed aansluit bij Agile methoden, waarbij non-functional requirements ingevuld kunnen worden in een compact gebleven framework. In die context kijken we naar:</p>
<ul>
<li>applicaties deployen op allerlei platformen en omgevingen;</li>
<li>applicaties automatisch installeren en updaten;</li>
<li>applicaties voorzien van management interfaces;</li>
<li>product software uitbreidbaar maken middels een SDK;</li>
<li>product software verkopen als combinatie van standaard onderdelen en optionele uitbreidingen;</li>
<li>modulaire User Interfaces.</li>
</ul>
<p>De slides van de presentatie zijn te vinden op de <a href="http://www.nljug.org/pages/events/content/jfall_2009/sessions/00018/">NLJUG website</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/online-video-beyond-osgi-software-architecture/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Swing &amp; OSGi &#8212; please play nice!</title>
		<link>http://lsd.luminis.nl/en/swing-and-osgi/</link>
		<comments>http://lsd.luminis.nl/en/swing-and-osgi/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 07:00:35 +0000</pubDate>
		<dc:creator>Angelo van der Sijpt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://lsd.luminis.nl/?p=421</guid>
		<description><![CDATA[OSGi is dynamic, Swing is static; these properties tend to bite each other. We will show some of the pitfalls you will encounter in a nontrivial OSGi-Swing application, and show how to give up a little bit of flexibility to get around them.]]></description>
			<content:encoded><![CDATA[<p>In a recent <a href="http://java.dzone.com/articles/plugable-swing-%E2%80%93-hello-world" target="_blank">blog</a> by Peter Karich, he showed how to create a pluggable Swing application using OSGi. While this works fine for smaller examples, you might run into more serious issues once you application starts to grow.</p>
<h2>Plugging Swing: it leaks?</h2>
<p>Let&#8217;s start with an application not unlike the one from aforementioned blog; it uses a window as host, and has a pluggable menu, and a pluggable table.</p>
<p><a href="http://lsd.luminis.nl/wp-content/uploads/2009/10/SWING_OSGI_Pluggable-components600.jpg"><img class="size-full wp-image-435 alignnone" title="SWING_OSGI_Pluggable components600" src="http://lsd.luminis.nl/wp-content/uploads/2009/10/SWING_OSGI_Pluggable-components600.jpg" alt="SWING_OSGI_Pluggable components600" width="350" height="150" /></a></p>
<p>You can find the code we used at the end of this entry (or, for the impatient, <a href="http://lsd.luminis.nl/wp-content/uploads/2009/10/swing_osgi.zip">here</a>).</p>
<p>Using this pluggable system, we could end up with several curious situations. For instance, you might have a mixed look and feel in you application.</p>
<p><a href="http://lsd.luminis.nl/wp-content/uploads/2009/10/SWING_OSGI_wrong_menus.png"><img class="size-full wp-image-444 alignnone" title="SWING_OSGI_wrong_menus" src="http://lsd.luminis.nl/wp-content/uploads/2009/10/SWING_OSGI_wrong_menus.png" alt="SWING_OSGI_wrong_menus" width="250" height="350" /></a></p>
<p>Or worse, you might end up with a UI that (sometimes) fails to start, and spits a stacktrace your way.</p>
<p><a href="http://lsd.luminis.nl/wp-content/uploads/2009/10/swing_osgi_NPE.png"><img class="alignnone size-full wp-image-528" title="swing_osgi_NPE" src="http://lsd.luminis.nl/wp-content/uploads/2009/10/swing_osgi_NPE.png" alt="swing_osgi_NPE" width="350" height="170" /></a></p>
<h2>It leaks, but why?</h2>
<p>Our host, and all components have been stored in separate bundles, meaning we don&#8217;t have full control about the order in which actions are performed (more about that later). However, we do know there are orders of execution that are less than ideal; let&#8217;s force one of those.</p>
<p>The <a href="http://lsd.luminis.nl/wp-content/uploads/2009/10/swing_osgi.zip">project</a> contains an Ant script to make things easier. From the root of the extracted project, run</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #000000; font-weight: bold;">&amp;</span>gt; ant run1</pre></div></div>

<p>This starts the framework, installing the necessary bundles, but does not start them (note that this step uses <a href="http://paxrunner.ops4j.org">Pax Runner</a>, and therefore needs internet access). We can now start our bundles in the order we like.</p>
<h3>A tale of two look-and-feels</h3>
<p>After starting the framework, wait for the &#8220;Welcome to Felix&#8221; message, and run</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span> Welcome to Felix
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span> ================
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>
start <span style="color: #000000;">2</span>
start <span style="color: #000000;">1</span></pre></div></div>

<p>The situation arises because the look and feel is a static concept in Swing. The menu bundle creates its <code>JMenu</code> <em>before</em> (see Menu.java, ln 30) the host sets its look and feel (Host.java, ln 51), and keep that look and feel, even when the host bundle changes it later.</p>
<h3>Tables, ScrollPanes and NPEs</h3>
<p>The NullPointerException above is a different story, but it goes back to the same staticness of Swing too. To force this situation, start only bundle 4.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span> Welcome to Felix
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span> ================
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>
start <span style="color: #000000;">4</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span> Exception <span style="color: #000000; font-weight: bold;">in</span> thread <span style="color: #ff0000;">&quot;AWT-EventQueue-0&quot;</span> java.lang.NullPointerException
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at net.luminis.swingosgi.part1.scrolltable.impl.TableComponent$1.run<span style="color: #7a0874; font-weight: bold;">&#40;</span>TableComponent.java:<span style="color: #000000;">31</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.event.InvocationEvent.dispatch<span style="color: #7a0874; font-weight: bold;">&#40;</span>InvocationEvent.java:<span style="color: #000000;">209</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.EventQueue.dispatchEvent<span style="color: #7a0874; font-weight: bold;">&#40;</span>EventQueue.java:<span style="color: #000000;">633</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.EventDispatchThread.pumpOneEventForFilters<span style="color: #7a0874; font-weight: bold;">&#40;</span>EventDispatchThread.java:<span style="color: #000000;">296</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.EventDispatchThread.pumpEventsForFilter<span style="color: #7a0874; font-weight: bold;">&#40;</span>EventDispatchThread.java:<span style="color: #000000;">211</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.EventDispatchThread.pumpEventsForHierarchy<span style="color: #7a0874; font-weight: bold;">&#40;</span>EventDispatchThread.java:<span style="color: #000000;">201</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.EventDispatchThread.pumpEvents<span style="color: #7a0874; font-weight: bold;">&#40;</span>EventDispatchThread.java:<span style="color: #000000;">196</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.EventDispatchThread.pumpEvents<span style="color: #7a0874; font-weight: bold;">&#40;</span>EventDispatchThread.java:<span style="color: #000000;">188</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
     <span style="color: #7a0874; font-weight: bold;">&#91;</span>java<span style="color: #7a0874; font-weight: bold;">&#93;</span>      at java.awt.EventDispatchThread.run<span style="color: #7a0874; font-weight: bold;">&#40;</span>EventDispatchThread.java:<span style="color: #000000;">122</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Let&#8217;s take a look at the line where this NPE happens:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">JScrollPane</span> scrollPane <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JScrollPane</span><span style="color: #009900;">&#40;</span>table<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
scrollPane.<span style="color: #006633;">getColumnHeader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setBackground</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Color</span>.<span style="color: #006633;">blue</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
m_panel.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>scrollPane<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We know that the <code>ColumnHeader</code> is null. This is because its <code>JTable</code>&#8217;s responsibility to create the header, but this is only done once the table knows it is part of an AWT hierarchy. The following lines come from the 1.5 JDK on a Mac; <code>configureEnclosingScrollPane()</code> creates the column header. This <code>addNotify</code> method comes from <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Component.html#addNotify%28%29">Component</a>, and notifies of, exactly, the event of being added to an AWT container.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> addNotify<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">addNotify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  configureEnclosingScrollPane<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Order, order!</h2>
<p>So, the static nature of Swing and the dynamic nature of OSGi seem to hurt each other seriously here.</p>
<p>One way to get the application right is by fixing the order in which Swing components can be created. By starting bundle 1 first in our application, we at least fix the look and feel. Getting the scrolling table to run correctly is an entirely different story.</p>
<p>Regarding order, a few possible solutions spring to mind immediately,</p>
<ol>
<li>Put all UI stuff in one bundle</li>
<li>Use OSGi bundle start levels</li>
</ol>
<p>Sure, all UI in a single bundle will give you the control necessary, but it also defeats the purpose. OSGi start levels can at least solve the ordering issues, but will not get you out of the NullPointerException and might have more impact than you desire.</p>
<h3>What order?</h3>
<p>As we have seen, absolute order does not solve our problem. How about separating creation and initialization? Still, we need to impose some order, or at least some hierarchy.</p>
<p><img class="alignnone size-full wp-image-446" title="SWING_OSGI_Application composition600" src="http://lsd.luminis.nl/wp-content/uploads/2009/10/SWING_OSGI_Application-composition600.jpg" alt="SWING_OSGI_Application composition600" width="446" height="210" /></p>
<p>We represent each Swing component by an OSGi service, and leverage the OSGi service dependency resolution to build up our hierarchy; this way, we know the host service will be started last.</p>
<ol>
<li><strong>Resolve services</strong> Once the host bundle starts, we know all components are locked and loaded; the host can now start setting up Swing&#8217;s static elements like the look and feel.</li>
<li><strong>Create components</strong> Component creation ripples downward: the host gets its direct children, adding them to its container, and in the process triggering the children to get their child components.</li>
<li><strong>Initialize components</strong> Once the component creation is done, the host instructs each component to initialize; we can now be certain that all components are part of the AWT hierarchy.</li>
</ol>
<p>To reach this situation, we introduce a new OSGi service that wraps the component.</p>
<p><img class="alignnone size-full wp-image-447" title="SWING_OSGI_Using component provider600" src="http://lsd.luminis.nl/wp-content/uploads/2009/10/SWING_OSGI_Using-component-provider600.jpg" alt="SWING_OSGI_Using component provider600" width="447" height="219" /></p>
<p>All components are handled by a service implementing <code>ComponentProvider</code>; notice how methods are required to be called on the EventDispatchThread, making sure that all components are created on the EDT, while retaining the order necessary.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> ComponentProvider <span style="color: #009900;">&#123;</span>
 <span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Constant to identify ComponentProvider services.
 */</span>
 <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> COMPONENT_ID_KEY <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;component.id&quot;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * This function should always be called from the EDT. The implementor
 * may assume that this function is called once and before {@link #addedToContainer()}
 *
 * @return the implementors (Swing) component which it provides.
 */</span>
 <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">JComponent</span> getComponent<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
 <span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Triggered when the component is added to a container. The implementation
 * can validate some stuff. This function must be called on the EDT.
 * Implementors may assume this function is called after {@link #getComponent()}.
 */</span>
 <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> addedToContainer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <code>getComponent</code> function is analogous to the <em>create</em> step above; the <code>addedToContainer</code> triggers the <em>initialize</em>.</p>
<h3>Let&#8217;s try that out!</h3>
<p>To check that this actually works OK, run</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #000000; font-weight: bold;">&amp;</span>gt; ant run2</pre></div></div>

<p>from the root of the project, and start the bundles in any order you like. The UI will only show up once <em>all required</em> components are available; notice that the <code>Table</code> and the <code>ScrollPane</code> component can be used interchangeably.</p>
<h2>Is it all good?</h2>
<p>For the most part, yes. You do give up some flexibility: the UI is assembled at runtime, but it is no longer possible to (easily) plug components into a running system without special provisions. Then again, how often do you deploy new Swing-based functionality to a <em>running</em> application?</p>
<p>In the example application, we use ServiceTrackers to keep track of the components needed by the host. In a real system, you should consider using some dependency management mechanism; we have used the <a href="http://felix.apache.org/site/apache-felix-dependency-manager.html">Apache Felix Dependency Manager</a> in the past.</p>
<h2>The project and the story</h2>
<p>The project mentioned above is available as a zipped <a href="http://lsd.luminis.nl/wp-content/uploads/2009/10/swing_osgi.zip">Eclipse project</a>. You can directly import this into Eclipse, or just unzip it and run the Ant build file.</p>
<p>To run the examples, you will need <a href="http://ant.apache.org/">Apache Ant</a>. Also, since we use <a href="http://paxrunner.ops4j.org/space/Pax+Runner">Pax Runner</a>, you will need an internet connection.</p>
<p>The presentation we gave about this at Devoxx 09 is at SlideShare.</p>
<div style="width:425px;text-align:left" id="__ss_2527491"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/angelovds/swing-osgi-devoxx-09" title="Swing &amp; OSGi - Devoxx 09">Swing &amp; OSGi &#8211; Devoxx 09</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=swingandosgi-devoxx09-091118073831-phpapp01&#038;rel=0&#038;stripped_title=swing-osgi-devoxx-09" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=swingandosgi-devoxx09-091118073831-phpapp01&#038;rel=0&#038;stripped_title=swing-osgi-devoxx-09" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/angelovds">Angelo van der Sijpt</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/swing-and-osgi/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Oredev 2009</title>
		<link>http://lsd.luminis.nl/en/oredev-2009/</link>
		<comments>http://lsd.luminis.nl/en/oredev-2009/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 22:44:59 +0000</pubDate>
		<dc:creator>Angelo van der Sijpt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[News Item]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[Øredev]]></category>

		<guid isPermaLink="false">http://lsd.luminis.nl/?p=486</guid>
		<description><![CDATA[4 - 6 November I went to Øredev, probably the largest developer conference in Scandinavia. Time for some highlights...]]></description>
			<content:encoded><![CDATA[<p><b>Update 2010-05-08</b><br />
The video of my session is up! Check it out at <a href="http://oredev.com/videos/dynamic-deployment-with-osgi">http://oredev.com/videos/dynamic-deployment-with-osgi</a>.</p>
<p>This past week (4 &#8211; 6 November), I went to <a href="http://www.oredev.com">Øredev</a>, probably the largest developer conference in Scandinavia. I had been invited as a speaker, thanks for having me!</p>
<h3>Great food, nice ambiance</h3>
<p>The first thing that strikes me about this conference is how well it has been prepared. The food is great, there is a good evening program, and overall both your inner geek and inner person are well looked after.</p>
<h3>Highlights</h3>
<p><strong>Interactive Visualizations from Microsoft research &#8211; Eric Stollnitz (User Experience track)<br />
<span style="font-weight: normal;">One of the rare talks I actually did not like. Having not read the session description properly, I had totally wrong expectations; the session demoed visual tools like <a href="http://livelabs.com/photosynth/">Photosynth</a>, which are cool, but not something we haven&#8217;t seen before. And besides, running Vista on a Mac, and having to kill Internet Explorer&#8230;?</span></strong></p>
<p><strong><span style="font-weight: normal;"><strong>Open source Java: ten things you didn&#8217;t know you could do &#8211; Terrence Barr (Java track) </strong><br />
Early in the talk it felt like a plug for the greatness of Sun, making Java open source. Later, however, it mentions some <em>seriously</em> cool technology that has become possible now! Some honorable mentions,</span></strong></p>
<ul>
<li>The <a href="http://research.sun.com/projects/maxine/">Maxine guest VM</a> is an effort to run a Java VM directly on a HyperVisor, skipping the entire OS!</li>
<li><a href="http://www.ikvm.net/">IKVM.NET</a> is a project aiming to run Java code on a .NET VM. Somehow, it turns out that Java bytecode and .NET assembly language are so similar, that an effort has been started to create automatic translation tools between compiled Java and compiled .NET (and vice versa). I would like to add that this is allows not only Java to run on a .NET VM, but likely any language that runs on the Java VM! Interesting&#8230;</li>
<li><a href="http://icedtea.classpath.org/wiki/ZeroSharkFaq#What_is_Zero.3F">Zero</a> writes a Java VM in plain C without using assembler code, making it easier to port it to new platforms.</li>
</ul>
<p><strong>The Manager&#8217;s Guide to Agile Adoption &#8211; Mike Cottmeyer (PM In Practice track)</strong><br />
A great talk showing the issues that might hamper agile adoption, especially in larger organizations. Some snippets,</p>
<ul>
<li>&#8220;Agile adoption at the team level is not the issue, it&#8217;s adopting agile <em>across</em> teams.&#8221;</li>
<li>Don&#8217;t speak of features of a system, speak of capabilities (think about that one!)</li>
<li>Depending on the amount of dependencies between teams, we could use a Scrum of Scrums (resource dependency), Product Owner team (requirements dependency), or a Product Owner team with Architects (technical dependencies). Whatever method is used, this higher level should build a <em>normalized</em> backlog, intended to create some alignment along the teams. The team&#8217;s backlogs are based on this normalized backlog.</li>
<li>Feature teams will break down at some level; at a certain system size, it&#8217;s no longer possible to create a top-to-bottom slice of the system which is small enough for a single team to manage.</li>
</ul>
<p>In short, I really enjoyed this talk, and I feel there might be some applications for these ideas somewhere near me&#8230;</p>
<p><strong>How Exactly Can Developers Create a Compelling User Experience? &#8211; Ben Galbraith (User Experience track)</strong><br />
Exactly the way I would expect a user experience talk to look (and feel!) like: polished imagery, a well-oiled story line, and lots of inspiration. Besides, I have two new books to add to my reading list: <a href="http://www.bol.com/nl/p/boeken-engels/about-face-3/1001004004709687/index.html">About Face</a> by Alan Cooper, which seems to be the standard volume on interaction design, and <a href="http://www.bol.com/nl/p/boeken-engels/the-humane-interface/1001004001047367/index.html">The humane interface</a> by Jeff Raskin.</p>
<p><strong>Reconsidering cherished design dogmas &#8211; Johannes Brodwall &amp; Finn-Robert Kristensen (Architecture track)</strong><br />
I actually had a beer with these guys a few days earlier, and they told me about their ideas. In short, there are a number of dogmas in software design we came to hold true, but are they actually true? For instance, is generic code really more reusable than specific code?</p>
<p>It&#8217;s a shame the talk didn&#8217;t really come across, and I could not put my finger on the problem; it might have something to do with the over-abstracted example they chose.</p>
<p><strong>Dynamic Deployment with OSGi &#8211; Angelo van der Sijpt (Java track)</strong><br />
Well, let the crowds decide on this one. Have you visited my talk, and have an opinion about it? Let me know in the comments?</p>
<p><strong>Modeling in the Age of Agility &#8211; Kevlin Henney (Agile Architecture track)</strong><br />
&#8220;Working software over comprehensive documentation&#8221; sounds good, but how about modeling? Are all models potential waste? Of course not, but when applying modeling because it is modeling, is sure to create models no one will ever look at, and the few good ones in there are buried. Some snippets,</p>
<ul>
<li>&#8220;Agile is all about doing.&#8221; Actually, I did not know the word &#8216;Agile&#8217; comes from the Latin verb for &#8216;to do&#8217;.</li>
<li>&#8220;The most important aspect of modeling is the -ing.&#8221;</li>
</ul>
<h3>So?</h3>
<p>Like I said, a great conference, and I&#8217;m sorry I missed the test track. I will leave you with a quote I picked up on Twitter (I don&#8217;t know which session it&#8217;s from),</p>
<p>&#8220;Don&#8217;t build frameworks, extract them&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/oredev-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nieuwe iPhone applicatie gelanceerd: Quote eetgids</title>
		<link>http://lsd.luminis.nl/en/nieuwe-iphone-applicatie-gelanceerd-quote-eetgids/</link>
		<comments>http://lsd.luminis.nl/en/nieuwe-iphone-applicatie-gelanceerd-quote-eetgids/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 07:03:12 +0000</pubDate>
		<dc:creator>Arjan Schaaf</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[appstore]]></category>
		<category><![CDATA[eetgids]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[luminis]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[News Item]]></category>
		<category><![CDATA[quote]]></category>
		<category><![CDATA[quotenet]]></category>

		<guid isPermaLink="false">http://lsd.luminis.net/?p=284</guid>
		<description><![CDATA[luminis software development en luminis live hebben een nieuwe iPhone applicatie gelanceerd: de quote eetgids.]]></description>
			<content:encoded><![CDATA[<p>Op 1 oktober was het zover, de <a href="http://www.quotenet.nl">Quote</a> eetgids staat in de Apple Appstore! Met de Quote eetgids kan je op eenvoudige wijze restaurants in de buurt vinden en beoordelen. Dit op basis van je huidige lokatie die met behulp van GPS wordt vastgesteld. Heb je andere voorkeuren? Alleen met gelegenheden met michelinster? Of na een heerlijke dag varen, aanleggen bij de steiger met zicht op je blinkende jacht van een voortreffelijk menu genieten? Check de Quote eetgids!</p>
<table border="0">
<tbody>
<tr>
<td><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=331587849&#038;mt=8"><img src="http://lsd.luminis.net/wp-content/uploads/2009/10/app-store-badge-300x98.png" alt="installeer de Quote eetgids" title="installeer de Quote eetgids" width="300" height="98" class="size-medium wp-image-285" /></td>
<td>Ontwerp: <a href="http://www.luminislive.nl">luminis live</a><br />
Technische<br />
realisatie: <a href="http://lsd.luminis.nl">luminis software development</a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/nieuwe-iphone-applicatie-gelanceerd-quote-eetgids/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NHibernate Lambda Extensions &#8211; an open-source adventure</title>
		<link>http://lsd.luminis.nl/en/nhibernate-lambda-extensions-an-open-source-adventure/</link>
		<comments>http://lsd.luminis.nl/en/nhibernate-lambda-extensions-an-open-source-adventure/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 11:51:17 +0000</pubDate>
		<dc:creator>Richard de Zwart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[lambda]]></category>
		<category><![CDATA[nhibernate]]></category>

		<guid isPermaLink="false">http://lsd.luminis.net/?p=215</guid>
		<description><![CDATA[When you want to get rid of magic strings in your NHibernate queries, lambdas are the way to go. ]]></description>
			<content:encoded><![CDATA[<p>For our client <a href="http://www.mg-dejong.nl/" target="_blank">Gerechtsdeurwaarderskantoor De Jong</a> we built a .NET application that uses NHibernate in the data-layer to talk to the Informix database. To abstract away from the specific knowledge about the database / ORM I created the below structure:</p>
<p><img src="http://blog.luminis.nl/luminis/resource/richardz/StorageDiagram.png" /></p>
<p>The DomainConnector is a class that implements lots of business rules to load/save domain-objects and gets its IStorage from our IoC-container (which is <a href="http://www.castleproject.org" target="_blank">Castle Windsor</a>). The InformixConnector implements the IStorage interface, but the DomainConnector doesn&#8217;t know that. Just as it doesn&#8217;t know that the InformixConnector uses NHibernate to do the actual work.
</p>
<p>
Well, until recently that was not entirely the case. The DomainConnector needs queries to specify which objects it wants in a list (for example). Those queries were in strings and were actually HQL queries.<br/><br />
Mmmmmmmh, so the DomainConnector did not know what database was in the back-end (thanks to NHibernate), but did know in some way about the fact that NHibernate was used. Use invalid HQL in your query and you&#8217;re doomed.
</p>
<p>Some times you can live with less-than-perfect code. But a couple of days ago I ran into a problem I felt I had had before. I got this message from NHibernate that it could not map some property. So what do you do? You check your mapping file and the class that it maps to and conclude that everything is perfect. So you Google. Nothing interesting.
</p>
<p>And then (a frustrating hour later) a memory bubbles up: it is not talking about the mapping itself, it&#8217;s talking about trying to map names in a query! Yep, that was the problem. The cause? I changed the name of a property. The real cause? This property was referenced in a string and the compiler could -of course- not warn me I had to change the query-string.
</p>
<p>I had e feeling that Lambda-expressions must be the solution to this problem (as they are currently to a lot of my problems). And Google (as a .NET afficionado should I be <a href="http://www.bing.com" target="_blank">bing-ing</a>?) told me there was already an open-source project that did just what I wanted:<br />
<a href="http://code.google.com/p/nhlambdaextensions/">nhlambdaextensions</a>.
</p>
<p>This project contains a few extension classes that allow you to use lambdas to specify your ICriteria. As they say on their homepage:</p>
<pre>
    .Add(Expression.Eq("Name", "Smith"))

becomes

    .Add<Person>(p => p.Name == "Smith")
</pre>
</p>
<p>
Now you can have Intellisense and compile-time checking. No way you inadvertently type LastName in stead of Name!
</p>
<p>
So I downloaded the binaries, tried to compile, noticed that I needed a newer version of NHibernate, downloaded that and it compiled. Changed one of the DomainConnectors and ran a unit test: bingo!!! This was going to work. I was so happy, I changed all the DomainConnectors before running an intergration test. I mean: I changed all the code before actually running it against NHibernate. *** UGLY WORDS *** when I did that eventually. For some obscure reason the SessionFactory could no longer be created, so no database access&#8230;
</p>
<p>
Reverting to the previous version of NHibernate solved this (I love version-control), but then I could not compile my lambdas anymore. So what should I do now: try to solve the SessionFactory problem or revert to the queries-in-a-string version of my DomainConnector. Tough descision.
</p>
<p>And then I had my epiphany: this is open-source code. I can download the code, add it to my project, compile it against my working version of NHibernate and have lambda-based queries. Have your cake and eat it too!</p>
<p>
It took no more than 10 minutes to achieve this. That&#8217;s the beauty of open-source, take control. But it also gave me more responsibility than I might actually want. Now this code was sort-of <i>my</i> code. Would I do that for larger open-source project like NHibernate itself? No way, my client&#8217;s business depends on the use of NHibernate. I want to be sure I have a stable, correctly compiled version of it. But for this 6 classes, 500 lines of code project I feel ok.</p>
<p>
I even solved a bug that I might contribute to the project. Did not do that yet, though. Small steps&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/nhibernate-lambda-extensions-an-open-source-adventure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using GWT to create an OSGi-aware web application</title>
		<link>http://lsd.luminis.nl/en/using-gwt-to-create-an-osgi-aware-web-application/</link>
		<comments>http://lsd.luminis.nl/en/using-gwt-to-create-an-osgi-aware-web-application/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 20:14:29 +0000</pubDate>
		<dc:creator>Angelo van der Sijpt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apache ACE]]></category>
		<category><![CDATA[Apache Felix]]></category>
		<category><![CDATA[extender]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[pax]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[smartservices]]></category>
		<category><![CDATA[toolkit]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://lsd.luminis.net/?p=217</guid>
		<description><![CDATA[<p><a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a> is cool, and so is OSGi. However, creating a web application that can use OSGi services is not that easy. By the end of this tutorial, you will have created a GWT project that delivers a usable jar. If you're impatient, skip to the end for the downloadable Eclipse project.</p>]]></description>
			<content:encoded><![CDATA[<p><strong>Update 2010-02-20</strong> <em>Both Pax Runner 1.3.0 and GWT 2.0 have caused quite some changes to this post. I have tried to stay up to date as well as I could (the zipped project now uses GWT 2.0), but you might find some inconsistencies when following the tutorial.</em></p>
<p><a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a> is cool, and so is OSGi. However, when building a web UI for <a href="http://cwiki.apache.org/confluence/display/ACE/Index">Apache ACE</a>, I found out that creating a web application that can use OSGi services is not that easy. By the end of this tutorial, you will have created a GWT project that delivers a usable jar. If you&#8217;re impatient, skip to the end for the downloadable Eclipse project.</p>
<h3>Step 1: Create a GWT project</h3>
<p>Create a regular GWT project using the regular webAppCreator; this will give you a project that includes an <a href="http://ant.apache.org">Ant</a> buildfile, we will need that later on.</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">angelos:workspace angelos$ ./gwt-mac-1.6.4/webAppCreator -out GwtDemo net.luminis.gwt.gwtdemo
Created directory GwtDemo/src
Created directory GwtDemo/war
Created directory GwtDemo/war/WEB-INF
Created directory GwtDemo/war/WEB-INF/lib
Created directory GwtDemo/src/net/luminis/gwt
Created directory GwtDemo/src/net/luminis/gwt/client
Created directory GwtDemo/src/net/luminis/gwt/server
Created file GwtDemo/src/net/luminis/gwt/gwtdemo.gwt.xml
Created file GwtDemo/war/gwtdemo.html
Created file GwtDemo/war/gwtdemo.css
Created file GwtDemo/war/WEB-INF/web.xml
Created file GwtDemo/src/net/luminis/gwt/client/gwtdemo.java
Created file GwtDemo/src/net/luminis/gwt/client/GreetingService.java
Created file GwtDemo/src/net/luminis/gwt/client/GreetingServiceAsync.java
Created file GwtDemo/src/net/luminis/gwt/server/GreetingServiceImpl.java
Created file GwtDemo/build.xml
Created file GwtDemo/README.txt
Created file GwtDemo/.project
Created file GwtDemo/.classpath
Created file GwtDemo/gwtdemo.launch
Created file GwtDemo/war/WEB-INF/lib/gwt-servlet.jar</pre></div></div>

<p>If you want to, you can import this project directly into your Eclipse. If you check the mark &#8220;use Google Web Toolkit&#8221; in the project properties, you can use all the same goodies that creating the project in Eclipse would have given you. Remember to replace the buildpath entries for gwt-user.jar and gwt-dev-*.jar by a Library import for GWT.</p>
<h3>Step 2: Include the necessary OSGi references</h3>
<p>Create an &#8216;ext&#8217; directory, and add org.osgi.core.jar to that. In Eclipse, add this jar to your build path.</p>
<h3>Step 3: Use OSGi services from your web applicaiton</h3>
<p>We will first add a simple Activator on the server side.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.luminis.gwt.server</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.osgi.framework.BundleActivator</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.osgi.framework.BundleContext</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> <span style="color: #003399;">Activator</span> <span style="color: #000000; font-weight: bold;">implements</span> BundleActivator <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> BundleContext m_context<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> BundleContext getContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> m_context<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> start<span style="color: #009900;">&#40;</span>BundleContext context<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
        m_context <span style="color: #339933;">=</span> context<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> stop<span style="color: #009900;">&#40;</span>BundleContext context<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Then, we up the GreetingServiceImpl to actually use this <a href="http://www.osgi.org/javadoc/r4v41/org/osgi/framework/BundleContext.html">BundleContext</a> (note that we use it directly here, but you could use it to get other services, create a <a href="http://www.osgi.org/javadoc/r4v41/org/osgi/util/tracker/ServiceTracker.html">ServiceTracker</a>, etc.)</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> greetServer<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> input<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003399;">String</span> serverInfo <span style="color: #339933;">=</span> getServletContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getServerInfo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003399;">String</span> userAgent <span style="color: #339933;">=</span> getThreadLocalRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;User-Agent&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;Hello, &quot;</span> <span style="color: #339933;">+</span> input <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;!
&nbsp;
I am running &quot;</span> <span style="color: #339933;">+</span> serverInfo
    <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;.
&nbsp;
It looks like you are using:&quot;</span> <span style="color: #339933;">+</span> userAgent <span style="color: #339933;">+</span>
    <span style="color: #0000ff;">&quot;The framework we run from has &quot;</span> <span style="color: #339933;">+</span> <span style="color: #003399;">Activator</span>.<span style="color: #006633;">getContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getBundles</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">length</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; bundles in it.&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Step 4: Add OSGi dependencies for the compiler</h3>
<p>Add our OSGi dependencies to the classpath, so the compiler can find all of it.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;">&lt;!-- Add any additional non-server libs (such as JUnit) --&gt;</span></pre></div></div>

<p>Right, let&#8217;s give it a try!</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">angelos:GwtDemo angelos$ ant war
Buildfile: build.xml
&nbsp;
...some output removed...
&nbsp;
war:
[zip] Building zip: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.war
&nbsp;
BUILD SUCCESSFUL
Total time: 36 seconds</pre></div></div>

<p>You will find a war in your project directory now. There still is one ingredient we need. We need to make this into a proper bundle. We can use <a href="http://www.aqute.biz/Code/Bnd">bnd</a> to help us with that.</p>
<h3>Step 5: use bnd to create a proper war</h3>
<p>Download bnd, and put into a lib directory, and add it to your buildfile.</p>
<p>We create a new target that transforms our war into a jar.</p>

<div class="wp_syntax"><div class="code"><pre class="ant" style="font-family:monospace;">&lt;target name=&quot;jar&quot;&gt;
    &lt;copy file=&quot;gwtdemo.war&quot; tofile=&quot;gwtdemo.jar&quot;/&gt;
    &lt;echo file=&quot;gwtdemo.bnd&quot;&gt;Import-Package: junit.framework;resolution:=optional, com.google.gwt.*;resolution:=optional, org.w3c.*;resolution:=optional, sun.misc;resolution:=optional, javax.imageio;resolution:=optional, javax.servlet.*;resolution:=optional, *
Bundle-Name: GWT Demo
Bundle-ClassPath: WEB-INF/classes, WEB-INF/lib/gwt-servlet.jar
Bundle-SymbolicName: net.luminis.gwt.gwtdemo
Webapp-Context: gwtdemo
Bundle-Activator: net.luminis.gwt.server.Activator
    &lt;/echo&gt;
    &lt;bndwrap jars=&quot;gwtdemo.jar&quot; output=&quot;gwtdemo.jar&quot;/&gt;
    &lt;jar file=&quot;gwtdemo.jar&quot; update=&quot;true&quot;&gt;
    &lt;manifest&gt;
        &lt;attribute name=&quot;Bundle-ClassPath&quot; value=&quot;WEB-INF/classes, WEB-INF/lib/gwt-servlet.jar, .&quot;/&gt;
     &lt;/manifest&gt;
    &lt;/jar&gt;
    &lt;delete file=&quot;gwtdemo.bnd&quot;/&gt;
&lt;/target&gt;</pre></div></div>

<p>What&#8217;s happening here?</p>
<ul>
<li>we copy our war to the same file, but with a jar extension,</li>
<li>we create a file for bnd to use, stating that we
<ul>
<li>want optional imports for junit and the gwt benchmarks, and non-optional imports for everything else (that what the * is for),</li>
<li>have some classes that we want bnd to scan for finding dependencies,</li>
<li>want to use a given Webapp-Context (this is a <a href="http://paxrunner.ops4j.org/display/paxweb/WAR+Extender">Pax war extender</a> specific entry),</li>
</ul>
</li>
<li>let bnd do its magic,</li>
<li>update our manifest: we put the . back on the classpath. This is important for the web application to find all resources, but if we would tell bnd to do it like this, it would treat . as the root of the classpath.</li>
<li>Finally, we delete that temporary bnd file.</li>
</ul>
<p>What does that give us?</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">angelos:GwtDemo angelos$ ant jar
Buildfile: build.xml
&nbsp;
...some output removed...
&nbsp;
jar:
[copy] Copying 1 file to /Users/angelos/workspace/workspace/GwtDemo
[bndwrap] gwtdemo 41 910305
[bndwrap] Warnings
[bndwrap] Superfluous export-package instructions: [WEB-INF.classes.net, gwtdemo.gwt.standard.images, WEB-INF, gwtdemo, WEB-INF.classes.net.luminis.gwt, gwtdemo.gwt.standard, WEB-INF.classes.net.luminis, WEB-INF.lib, WEB-INF.classes, gwtdemo.gwt.standard.images.ie6, WEB-INF.classes.net.luminis.gwt.client, WEB-INF.classes.net.luminis.gwt.server, gwtdemo.gwt]
[jar] Updating jar: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.jar
[delete] Deleting: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.bnd
&nbsp;
BUILD SUCCESSFUL
Total time: 23 seconds</pre></div></div>

<p>That&#8217;s it! You can now deploy this jar into a framework that uses the pax web tools. Right, let&#8217;s give that a try.</p>
<p>Download <a href="http://paxrunner.ops4j.org/space/Pax+Runner">pax-runner</a>, and unzip that somewhere. Copy in your new jar, an try the following command</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">angelos:pax-runner angelos$ <span style="color: #c20cb9; font-weight: bold;">sh</span> bin<span style="color: #000000; font-weight: bold;">/</span>pax-run.sh <span style="color: #660033;">--profiles</span>=war,compendium gwtdemo.jar</pre></div></div>

<p>Now visit <a href="http://localhost:8080/gwtdemo">http://localhost:8080/gwtdemo</a>:</p>
<p><img class="alignnone size-full wp-image-450" title="gwtdemo" src="http://lsd.luminis.nl/wp-content/uploads/2009/07/gwtdemo.png" alt="gwtdemo" width="500" height="432" /></p>
<h3>Summary</h3>
<p>So, what did we need?</p>
<ul>
<li>A fairly regular GWT project, create with an Ant file,</li>
<li>some code that tries to use OSGi services,</li>
<li>some bnd magic to make the war into a jar,</li>
<li>Pax tools to get it all running quickly.</li>
</ul>
<p>If you don&#8217;t want to use pax runner, you can need to deploy <a href="http://paxrunner.ops4j.org/display/paxweb/WAR+Extender">pax-web-extender-war</a>(<a href="http://repository.ops4j.org/mvn-snapshots/org/ops4j/pax/web/pax-web-extender-war/0.7.0-SNAPSHOT/pax-web-extender-war-0.7.0-20090623.160836-13.jar">jar</a>, snapshot 23 June) and an http server, preferably <a href="http://paxrunner.ops4j.org/display/paxweb/Pax+Web">pax-web-service</a>(<a href="http://repository.ops4j.org/maven2/org/ops4j/pax/web/pax-web-service/0.6.0/pax-web-service-0.6.0.jar">jar</a>), into your framework.</p>
<p>You can download the <a href='http://lsd.luminis.nl/wp-content/uploads/2009/07/gwtdemo.zip'>gwtdemo</a> Eclipse project to play around with it. I have not provided the GWT runtime in this download; you should edit line 4 of the build.xml to point to your installation of GWT.</p>
]]></content:encoded>
			<wfw:commentRss>http://lsd.luminis.nl/en/using-gwt-to-create-an-osgi-aware-web-application/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
