Friday, February 27, 2009

Embed OSGi to Monolithic Application as a Dynamic Plugin Mechanism

Eclipse Equinox is used as OSGi framework.

Run Equinox as a standalone application

Read Equinox tutorial.
C:\eclipse\plugins>java -jar org.eclipse.osgi_3.3.0.v20070530.jar -console

osgi> install file:d:\documents\temp\plugins\org.silentsquare.osgi.test.bundle.h
elloworld_1.0.0.jar
Bundle id is 1

osgi> ss

Framework is launched.

id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.0.v20070530
1 INSTALLED org.silentsquare.osgi.test.bundle.helloworld_1.0.0

osgi> start 1
Hello World!

osgi> ss

Framework is launched.

id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.0.v20070530
1 ACTIVE org.silentsquare.osgi.test.bundle.helloworld_1.0.0

osgi> close

Goodbye World!
Startup Equinox programmatically

See this blog article: "Starting Equinox from a Java application".

With org.eclipse.osgi_3.x.x.jar on classpath, which is just an ordinary jar file plus extra OSGi information, the code looks like
public class App {
public static void main(String[] args) throws Exception {
String[] equinoxArgs = {"-console"};
BundleContext context = EclipseStarter.startup(equinoxArgs,null);
Bundle bundle = context.installBundle("http://www.eclipsezone.com/files/jsig/bundles/HelloWorld.jar");
bundle.start();
for (Bundle b : context.getBundles()) {
System.out.println(b);
}
}
}

The next step would be to build Grimoires XMLView over OSGi and implement each pair of translators as OSGi bundle. But classloading could be tricky: translators need to use classes in Grimoires. How?

What OSGi Can Do For Me?

Two interesting usages of OSGi could be explored in my development context.

One is to use OSGi to componentize an existing complex application. Consider the OMII-UK website. As a web application, it has 3 logical functional units: the old repository that holds projects and releases and is almost obsolete, the new web front that also reads information from database about projects and releases, and the wiki based on JSPWiki. It will be nice to break them into 3 OGSi bundles to take advantage of the dynamics of OSGi bundles.

The other is to use OSGi to implement a dynamic extension framework for an originally monolithic application. In Grimoires, there is an XMLView interface that allows publishing any application domain specific service descriptions as long as they are in XML. Inside the implementation of XMLView, there is a pair of translators for each domain-specific description, translating to and from Grimoires' UDDI+WSDL+Metadata service description model. It will be good that we build XMLView over OGSi framework, and then each pair of translators will become an OSGi bundle. So if we want to support a new type of domain-specific service description, we add a corresponding bundle without bringing down Grimoires. If later this support is no longer needed, we remove the bundle without bringing down Grimoires.

These can be done because OSGi is claimed to be humble: it does not take over the whole JVM, and one Java application can even host multiple OSGi frameworks.

According to OSGi,
If you are developing software in Java then OSGi technology should be a logical next step because it solves many problems that you might not even be aware can be solved. The advantages of OSGi technology are so numerous that if you are using Java, then OSGi should be in your tool chest.
This seems reasonable because componentization looks like a natural approach towards software complexity.

Thursday, February 12, 2009

Google Protocol Buffer

Google Protocol Buffer can be used to serialise and deserialise structured data, either to/from a file, or to/from network. Protocol Buffer acts as a (network) protocol parser generator. It can generate a parser that understands a specific protocol format. Of course this can be implemented using a general purpose parser generator such as ANTLR.

Several existing solutions are available to address the same problem.
  • The problematic Java Serialization.
  • The DIY approach. It is surely painful in particular for complex data structure.
  • Serialise data to XML. In Java, this is supported by JAXB. The advantages of using XML as transmission format are that, XML is language independent, is platform independent, and is human readable. The disadvantage is the associated performance cost.
According to the Protocol Buffer's tutorial for Java, it has several selling points:
  • It has bindings for Java, C++, and Python. Thus the data can be transmitted between Java, C++, and Python applications.
  • Its performance is expected to be good, because not only it is not based on XML, but also it can boost the performance by not using Java reflection.
  • As long as following certain rules, when the protocol is updated, the new code is compatible with the old code.

Tuesday, February 03, 2009

java.lang.NullPointerException

In one of my previous blogs, I mentioned a map of downloads based on Google Maps API. To create such a map, first I collect IP addresses from where the downloads were initiated, then I use GeoLite City to translate the IP address to a geographic location on the Google map. GeoLite City is a free library with Java API, but of less precision than its commercial counterpart.

It was working fine for many month until recently it threw out the infamous java.lang.NullPointerException. NullPointerException might be the No.1 runtime exception. It is certainly for me.

A little investigation explains why NullPointerException happened. When I passed an IP address to the GeoLite City library, I naively assumed that GeoLite must be able to translate it into a geographic location, thus I did not check whether the Location object returned by GeoLite is null. So I was pulished. In fact, IP address allocation is dynamic, and an outdated GeoLite City library may not contain all the IP address information.

It was not rare I made such a naive mistake. The fundamental principle to avoid NullPointerException is that, when given an object reference, no matter it is from my own code or from outside my code, thinking defensively, reason the possibility that it may be null. To play safe, always check nullity.

An object reference could be given as a returned value of a method invocation, as method arguments when inside a method, or as a field member of a non-null object.