Yes, this is a somewhat long article. With no images, code samples, fancy screencasts or other visuals. It is just a story about me and my passion for OSGi. Perhaps there will be sequels, because there is still a lot to come. However, these intentions always seem to vanish over time so I am not making any promises.
In any case, I felt the urge to share my thus far little experience with real world OSGi. For a real customer with a real product on a small budget. Where software is developed by Average Joe or Jane and not by some cracker jack software guru flying around the world doing talks and publishing books. These people are of course working hard to make our life a better place while we just gloat over travelling abroad and back cover blurbs. So I thought: Lets help these fellows by sharing something about my personal experience with OSGi.
In short: The customer has a product consisting of a central server with a number of embedded devices connected over the internet. The server is a plain Java application with a Jetty web interface to operate, configure and monitor the system. In the near future, we want to extend the capabilities of the system and will of course result in more network and other domain related complexities.
When I started working at this project, a rudimentary rest interface for the server was already present and one of my jobs was to extend it to a full working version. Of course extensive testing was required, so I started by developing a simple tool to test a live rest service. It was sufficient to just let it fire a bunch of predefined http calls and log the results. I could extend it by automated validation and other should-haves later on. Eager to show off I started hacking away and the first requests were sent within the hour. Hardcoded urls launched from a static main method was the result but who cares? It was just a simple tool right?
After tinkering with Commons CLI for a bit, I started to think about other future needs. Next to a command line interface, repeatable tests or extensive logging could soon be needed. Such requirements were still uncertain and not that essential for the current state of the project. However, I did not want to rule them out by making it too hard to code in at a later stage. After all, these kinds of ‘simple’ programs tend to become an unmaintainable mess overnight.
If you are not thinking OSGi already you are not paying attention. What is more is that OSGi would be extremely useful for a new software version on the embedded devices. So the more hands-on experience, the merrier.
What you don’t want is vi to maintain manifest files. When it comes to OSGi, Bndtools is the only viable way to go, trust me. Unfortunately only available as Eclipse plugin yet, but the future is bright. Eclipse still has a grudge ever since I abandoned it for IntelliJ and I feel like I am still paying the price. But Bndtools is a loyal companion and creating bundles with correct dependencies, setting up run configurations, debugging and headless build support is a breeze.
The first thing I did for my test tool was searching for a bundle version of Apache’s httpclient. Marcel pointed to JPM and suggested to include the required bundles in the local workspace repository and just commit them in Git. For the Bndtools novice: You can set up local and remote repositories for external bundles. This allows you to easily setup package requirements for your own bundles. And JPM is very extensive when it comes to OSGi bundles for much well-known libraries.
Sometimes the only reason I want to use OSGi is because I just love using Java interfaces. These files with clear methods definitions always make me smile. Especially when they are defined as: “request(method, url)” or “saveResult()” when you are making a rest test tool. Of course this feeling is quickly gone when you have to implement them, but with OSGi I can delay these ‘trivialities’ until the software has to actually do something. At that point, all is spoiled and you start calling constructors and in OSGi’s case, the Service Registry.
To avoid a dependency hazard up front, I started to use Felix’ dependency manager. With a fluent API I was managing services like a skilled puppeteer. That is until you try to set up the run configuration and Bndtools is giving you a bit of a cryptic error when you hit the resolve button. Apparently I was missing some packages required by the dependency manager. Are these like meta dependencies? Anyhow, the video tutorials from Amdatu provided valuable help. It worked, but it was not ideal for a software engineer wanting to show off and just needed a quick fix. Whats wrong with the endless blogs with code samples and screenshots people used to write? 😉 Apparently my colleague thought this as well.
I started this story with the need for a command line interface, but until now it was still missing. Luckily, the Gogo shell of Felix provided just what I need. Next to basic bundle lifetime management, Gogo allows a simple method to implement your own commands. It is just a matter of setting some properties and adding some annotations. However, like most of these ‘easy-as-pie’-solutions, you have to invest a bit or more to learn them.
OSGi’s service layer is easy to understand, so for me it is mostly about figuring out the compendium and other service definitions. These libraries all differ in (documentation) quality. But then, how is that any different from plain Java libraries? I now have a simple test tool which I can easily extend with all kinds of result logging. I could add another UI or some automated way to launch the rest calls. All thanks to small and loosely coupled services. It kind of feels like ice skating on a lake: The joy of freedom and adrenaline you only understand when you feel the ice rushing under your skates. Don’t be afraid to fall!