Archief voor categorie Uncategorized
PhoneGap, een alternatief voor native mobiele applicaties
Geplaatst door Erik Sanders in Uncategorized, android, mobility op 17 augustus 2010
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 van PhoneGap.
iPhone
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 www.phonegap.com/apps). Er is tevens een getting started en er zijn extra plugins beschikbaar
Ondersteunde platformen
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.
| IPHONE | ANDROID | BLACKBERRY | SYMBIAN | PALM | |
| GEO LOCATION | √ | √ | √ | √ | √ |
| VIBRATION | √ | √ | √ | √ | √ |
| ACCELEROMETER | √ | √ | OS 4.7 | √ | √ |
| SOUND | √ | √ | √ | √ | √ |
| CONTACT SUPPORT | √ | √ | √ | √ | N/A |
Voor meer informatie zie www.phonegap.com
Who writes my user stories
Geplaatst door Albert Oudenampsen in Uncategorized, requirements op 19 juli 2010
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’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 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 “Yes, I get it! No worries, know what you need”, followed by a near endless code-and-fix cycles.
So user stories are great, but who writes them? Hmmm, users probably. After all it’s their story. Question is “can users write user stories”? The answer is simple: it depends….
Certainly some users can write user stories. Sysadmins can, helpdesk and application support too. But the “real” users, can they write user stories? I don’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 “unbalanced systems” like the ones in the famous what-if-airplanes picture. After all, you don’t build a system just to do application support or system admin (unless that is your business). You build systems to increase “business value” or whatever greater purpose and for that you need the “real” users.
As stated before: “any user and developer should be able to read a user story and immediately understand it”. If it is that simple, it cannot be too hard to learn how to write a user story.
A user story consists of two parts:
-Just a few lines of text that describe the problem;
-A Test that serves as an example and that can be used to determine when a story is complete.
A simple template for this can be found here: cukes.info
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….
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.
Barrister: how do we start?
Me: just go over the things you do during the day and see where your new system system comes in
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’s it.
Me: Hmmm, that is too simple, there must be more…..
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.
Or the cukes.info template:
In order to make as many visits as possible during a day
As a barrister
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.
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?
My conclusion: help your users in writing user stories and certainly help them in writing test scenario’s.
FitNesse and OSGi
Geplaatst door Angelo van der Sijpt in Uncategorized, java, technical op 25 mei 2010
As a demonstrator for a customer, I recently built a set of fixtures that allow FitNesse acceptance tests to talk to an OSGi framework. This code is by no means production quality, but merely intended to show the concept and explain the challenges.
I will not explain the details of the acceptance tests here, however, if there’s one point I would like to get across, it’s your fixtures should be as narrow as possible to easily accommodate for implementation changes. Study the different UserAdmin fixtures for more details. Also, I assume some familiarity with OSGi.
FitNesse and OSGi. Why?
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’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’s a different story.
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.
The big picture
The solution presented below uses a special ‘fixtures’ bundle, which can be deployed along side other bundles in your framework. This bundles exposes an interface (in our case, through an HTTPServlet), which is used by a set of connectors, which in turn are used by FitNesse.
The details
The ingredients are two parts connector code, one part boiler plate, and one part genuine OSGi-aware fixtures.
The connectors
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.
public void removeUser(String name) throws Exception { doRemoteCall(buildRemoteCall("UserAdmin", name), Void.class); }
This code instructs our RemoteInvoker to do some call to the outside world. For more details, see RemoteInvoker.java in the UserAdminRemoteFixtures project.
The fixture bundle
Moving one step closer to our service, and into the OSGi framework, we find a FixtureServlet, whose task it is to receive calls from the RemoteInvoker, and turn them into actual method calls on the fixtures.
The fixtures, then, are almost regular OSGi aware objects. I chose to use the Apache Felix Dependency Manager for the dependency management of the fixtures. So, for our UserAdmin fixture, the dependencies are
manager.add(createService() .setInterface(UserAdminListener.class.getName(), null) .setImplementation(userAdmin) .add(createServiceDependency() .setService(UserAdmin.class) .setRequired(true)));
Here, we state that we have some instance of a fixture userAdmin that registers itself as a UserAdminListener and needs a UserAdmin. How straightforward is that?
The final step takes us to the actual fixture,
public class UserAdminFixture implements UserAdminListener { private volatile UserAdmin m_userAdmin; ... public void addUser(String name) { m_usersCreatedInLastCall = 0; m_userAdmin.createRole(name, Role.USER); } ... }
which is just another component using a the UserAdmin service.
Putting it all together
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.
Future work
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
- a way to reduce the boiler plate code,
- a way to ensure that that both side of the fixtures use the same function naming, and
- better integration, for instance by only firing up a framework once a FitNesse suite is started.
Let’s play with it!
I have built a zip file 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 Apache Felix User Admin. A Readme gives you more information on getting it all up and running.
Meld je nu aan voor de AgileMDD kennissessie op 30 maart
Geplaatst door Richard van der Laan in Uncategorized op 10 maart 2010
![]()
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.
Aan de hand van vijf verschillende thema’s delen sprekers van diverse organisaties hun ervaringen met MDD in de praktijk: Thales Hengelo, Ministerie van Defensie, ArchitecIT, Delphino Consultancy en luminis.
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.
Datum: dinsdag 30 maart van 16:45 tot 20:00 uur
Locatie: IJsselburcht 3, 6825 BS, Arnhem
Voor wie: Architecten, ICT Managers en belangstellenden
Aanmelden: U kunt zich aanmelden per email door contact op te nemen met Inge Dokter
Het programma:
16:45 Opening in de grote zaal
17:00 Agile MDD: huidige trends en ontwikkelingen (Tony Sloos, Richard van der Laan)
17:30 MDA in realtime heterogene systemen (Rene van Hees, Alexander Broekhuis)
18:00 Lopend buffet
18:30 Microsoft DSL Toolkit in de praktijk (Gerrit Jan Timmermans, Erik Sanders)
19:00 MDD en software architectuur (Angelo Hulshout)
19:30 MDD kansen en risico’s (Andriy Levytskyy)
20:00 Afsluiting met borrel
Graag ontvangen we je aanmelding zo snel mogelijk, maar in iedergeval voor 12 maart. Aan deelname zijn geen kosten verbonden.
Je kan je aanmelding sturen naar Inge Dokter (inge.dokter@luminis.nl)
We hopen je te zien op dinsdag 30 maart!
Online video: Beyond OSGi software architecture
Geplaatst door Richard van der Laan in Uncategorized op 22 januari 2010
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. De gehele presentatie van 50 minuten kan je hier downloaden. Maar de eerste tien minuten zijn hieronder gelijk online te bekijken.
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’s) van die interfaces. Krachtige eigenschappen van dit model zijn:
- complexiteitsreductie door stricte scheiding van services;
- declaratieve services en dependency management (IoC);
- aspect oriëntatie op basis van stub services;
- security model.
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:
- applicaties deployen op allerlei platformen en omgevingen;
- applicaties automatisch installeren en updaten;
- applicaties voorzien van management interfaces;
- product software uitbreidbaar maken middels een SDK;
- product software verkopen als combinatie van standaard onderdelen en optionele uitbreidingen;
- modulaire User Interfaces.
De slides van de presentatie zijn te vinden op de NLJUG website.
Swing & OSGi — please play nice!
Geplaatst door Angelo van der Sijpt in Uncategorized, java op 18 november 2009
In a recent blog 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.
Plugging Swing: it leaks?
Let’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.
You can find the code we used at the end of this entry (or, for the impatient, here).
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.
Or worse, you might end up with a UI that (sometimes) fails to start, and spits a stacktrace your way.
It leaks, but why?
Our host, and all components have been stored in separate bundles, meaning we don’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’s force one of those.
The project contains an Ant script to make things easier. From the root of the extracted project, run
$ > ant run1This starts the framework, installing the necessary bundles, but does not start them (note that this step uses Pax Runner, and therefore needs internet access). We can now start our bundles in the order we like.
A tale of two look-and-feels
After starting the framework, wait for the “Welcome to Felix” message, and run
[java] Welcome to Felix [java] ================ [java] start 2 start 1
The situation arises because the look and feel is a static concept in Swing. The menu bundle creates its JMenu before (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.
Tables, ScrollPanes and NPEs
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.
[java] Welcome to Felix [java] ================ [java] start 4 [java] Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException [java] at net.luminis.swingosgi.part1.scrolltable.impl.TableComponent$1.run(TableComponent.java:31) [java] at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) [java] at java.awt.EventQueue.dispatchEvent(EventQueue.java:633) [java] at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296) [java] at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211) [java] at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201) [java] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196) [java] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188) [java] at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Let’s take a look at the line where this NPE happens:
JScrollPane scrollPane = new JScrollPane(table); scrollPane.getColumnHeader().setBackground(Color.blue); m_panel.add(scrollPane);
We know that the ColumnHeader is null. This is because its JTable’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; configureEnclosingScrollPane() creates the column header. This addNotify method comes from Component, and notifies of, exactly, the event of being added to an AWT container.
public void addNotify() { super.addNotify(); configureEnclosingScrollPane(); }
Order, order!
So, the static nature of Swing and the dynamic nature of OSGi seem to hurt each other seriously here.
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.
Regarding order, a few possible solutions spring to mind immediately,
- Put all UI stuff in one bundle
- Use OSGi bundle start levels
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.
What order?
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.

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.
- Resolve services Once the host bundle starts, we know all components are locked and loaded; the host can now start setting up Swing’s static elements like the look and feel.
- Create components 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.
- Initialize components 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.
To reach this situation, we introduce a new OSGi service that wraps the component.

All components are handled by a service implementing ComponentProvider; 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.
public interface ComponentProvider { /** * Constant to identify ComponentProvider services. */ public static final String COMPONENT_ID_KEY = "component.id"; /** * 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. */ public JComponent getComponent(); /** * 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()}. */ public void addedToContainer(); }
The getComponent function is analogous to the create step above; the addedToContainer triggers the initialize.
Let’s try that out!
To check that this actually works OK, run
$ > ant run2from the root of the project, and start the bundles in any order you like. The UI will only show up once all required components are available; notice that the Table and the ScrollPane component can be used interchangeably.
Is it all good?
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 running application?
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 Apache Felix Dependency Manager in the past.
The project and the story
The project mentioned above is available as a zipped Eclipse project. You can directly import this into Eclipse, or just unzip it and run the Ant build file.
To run the examples, you will need Apache Ant. Also, since we use Pax Runner, you will need an internet connection.
The presentation we gave about this at Devoxx 09 is at SlideShare.
Oredev 2009
Geplaatst door Angelo van der Sijpt in Uncategorized op 6 november 2009
Update 2010-05-08
The video of my session is up! Check it out at http://oredev.com/videos/dynamic-deployment-with-osgi.
This past week (4 – 6 November), I went to Øredev, probably the largest developer conference in Scandinavia. I had been invited as a speaker, thanks for having me!
Great food, nice ambiance
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.
Highlights
Interactive Visualizations from Microsoft research – Eric Stollnitz (User Experience track)
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 Photosynth, which are cool, but not something we haven’t seen before. And besides, running Vista on a Mac, and having to kill Internet Explorer…?
Open source Java: ten things you didn’t know you could do – Terrence Barr (Java track)
Early in the talk it felt like a plug for the greatness of Sun, making Java open source. Later, however, it mentions some seriously cool technology that has become possible now! Some honorable mentions,
- The Maxine guest VM is an effort to run a Java VM directly on a HyperVisor, skipping the entire OS!
- IKVM.NET 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…
- Zero writes a Java VM in plain C without using assembler code, making it easier to port it to new platforms.
The Manager’s Guide to Agile Adoption – Mike Cottmeyer (PM In Practice track)
A great talk showing the issues that might hamper agile adoption, especially in larger organizations. Some snippets,
- “Agile adoption at the team level is not the issue, it’s adopting agile across teams.”
- Don’t speak of features of a system, speak of capabilities (think about that one!)
- 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 normalized backlog, intended to create some alignment along the teams. The team’s backlogs are based on this normalized backlog.
- Feature teams will break down at some level; at a certain system size, it’s no longer possible to create a top-to-bottom slice of the system which is small enough for a single team to manage.
In short, I really enjoyed this talk, and I feel there might be some applications for these ideas somewhere near me…
How Exactly Can Developers Create a Compelling User Experience? – Ben Galbraith (User Experience track)
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: About Face by Alan Cooper, which seems to be the standard volume on interaction design, and The humane interface by Jeff Raskin.
Reconsidering cherished design dogmas – Johannes Brodwall & Finn-Robert Kristensen (Architecture track)
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?
It’s a shame the talk didn’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.
Dynamic Deployment with OSGi – Angelo van der Sijpt (Java track)
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?
Modeling in the Age of Agility – Kevlin Henney (Agile Architecture track)
“Working software over comprehensive documentation” 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,
- “Agile is all about doing.” Actually, I did not know the word ‘Agile’ comes from the Latin verb for ‘to do’.
- “The most important aspect of modeling is the -ing.”
So?
Like I said, a great conference, and I’m sorry I missed the test track. I will leave you with a quote I picked up on Twitter (I don’t know which session it’s from),
“Don’t build frameworks, extract them”
Nieuwe iPhone applicatie gelanceerd: Quote eetgids
Geplaatst door Arjan Schaaf in Uncategorized op 2 oktober 2009
Op 1 oktober was het zover, de Quote 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!
![]() |
Ontwerp: luminis live Technische realisatie: luminis software development |
NHibernate Lambda Extensions – an open-source adventure
Geplaatst door Richard de Zwart in Uncategorized op 10 juli 2009
For our client Gerechtsdeurwaarderskantoor De Jong 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:

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 Castle Windsor). The InformixConnector implements the IStorage interface, but the DomainConnector doesn’t know that. Just as it doesn’t know that the InformixConnector uses NHibernate to do the actual work.
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.
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’re doomed.
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.
And then (a frustrating hour later) a memory bubbles up: it is not talking about the mapping itself, it’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.
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 bing-ing?) told me there was already an open-source project that did just what I wanted:
nhlambdaextensions.
This project contains a few extension classes that allow you to use lambdas to specify your ICriteria. As they say on their homepage:
.Add(Expression.Eq("Name", "Smith"))
becomes
.Add(p => p.Name == "Smith")
Now you can have Intellisense and compile-time checking. No way you inadvertently type LastName in stead of Name!
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…
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.
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!
It took no more than 10 minutes to achieve this. That’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 my code. Would I do that for larger open-source project like NHibernate itself? No way, my client’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.
I even solved a bug that I might contribute to the project. Did not do that yet, though. Small steps….
Using GWT to create an OSGi-aware web application
Geplaatst door Angelo van der Sijpt in Uncategorized op 9 juli 2009
Update 2010-02-20 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.
Google Web Toolkit is cool, and so is OSGi. However, when building a web UI for Apache ACE, 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’re impatient, skip to the end for the downloadable Eclipse project.
Step 1: Create a GWT project
Create a regular GWT project using the regular webAppCreator; this will give you a project that includes an Ant buildfile, we will need that later on.
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
If you want to, you can import this project directly into your Eclipse. If you check the mark “use Google Web Toolkit” 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.
Step 2: Include the necessary OSGi references
Create an ‘ext’ directory, and add org.osgi.core.jar to that. In Eclipse, add this jar to your build path.
Step 3: Use OSGi services from your web applicaiton
We will first add a simple Activator on the server side.
package net.luminis.gwt.server; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { private static BundleContext m_context; public static BundleContext getContext() { return m_context; } public void start(BundleContext context) throws Exception { m_context = context; } public void stop(BundleContext context) throws Exception { } }
Then, we up the GreetingServiceImpl to actually use this BundleContext (note that we use it directly here, but you could use it to get other services, create a ServiceTracker, etc.)
public String greetServer(String input) { String serverInfo = getServletContext().getServerInfo(); String userAgent = getThreadLocalRequest().getHeader("User-Agent"); return "Hello, " + input + "! I am running " + serverInfo + ". It looks like you are using:" + userAgent + "The framework we run from has " + Activator.getContext().getBundles().length + " bundles in it."; }
Step 4: Add OSGi dependencies for the compiler
Add our OSGi dependencies to the classpath, so the compiler can find all of it.
<!-- Add any additional non-server libs (such as JUnit) -->Right, let’s give it a try!
angelos:GwtDemo angelos$ ant war Buildfile: build.xml ...some output removed... war: [zip] Building zip: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.war BUILD SUCCESSFUL Total time: 36 seconds
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 bnd to help us with that.
Step 5: use bnd to create a proper war
Download bnd, and put into a lib directory, and add it to your buildfile.
We create a new target that transforms our war into a jar.
<target name="jar">
<copy file="gwtdemo.war" tofile="gwtdemo.jar"/>
<echo file="gwtdemo.bnd">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
</echo>
<bndwrap jars="gwtdemo.jar" output="gwtdemo.jar"/>
<jar file="gwtdemo.jar" update="true">
<manifest>
<attribute name="Bundle-ClassPath" value="WEB-INF/classes, WEB-INF/lib/gwt-servlet.jar, ."/>
</manifest>
</jar>
<delete file="gwtdemo.bnd"/>
</target>What’s happening here?
- we copy our war to the same file, but with a jar extension,
- we create a file for bnd to use, stating that we
- want optional imports for junit and the gwt benchmarks, and non-optional imports for everything else (that what the * is for),
- have some classes that we want bnd to scan for finding dependencies,
- want to use a given Webapp-Context (this is a Pax war extender specific entry),
- let bnd do its magic,
- 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.
- Finally, we delete that temporary bnd file.
What does that give us?
angelos:GwtDemo angelos$ ant jar Buildfile: build.xml ...some output removed... 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 BUILD SUCCESSFUL Total time: 23 seconds
That’s it! You can now deploy this jar into a framework that uses the pax web tools. Right, let’s give that a try.
Download pax-runner, and unzip that somewhere. Copy in your new jar, an try the following command
angelos:pax-runner angelos$ sh bin/pax-run.sh --profiles=war,compendium gwtdemo.jar
Now visit http://localhost:8080/gwtdemo:

Summary
So, what did we need?
- A fairly regular GWT project, create with an Ant file,
- some code that tries to use OSGi services,
- some bnd magic to make the war into a jar,
- Pax tools to get it all running quickly.
If you don’t want to use pax runner, you can need to deploy pax-web-extender-war(jar, snapshot 23 June) and an http server, preferably pax-web-service(jar), into your framework.
You can download the gwtdemo 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.






