Tuesday, September 30, 2008

OSGi Commons: OSAMI?

Last year I was asked to participate in the OSAMI project, as part of the French equipe (I happen to live in France). So what is OSAMI?

OSAMI stands for: Open Source AMbient Intelligence. It is (or will be) a European funded project that will develop a large set of components targeting applications outside the PC and server world. That is, applications that directly affect your environment in which you live. We can all testify that computers play a larger and larger role in our lives, but making those devices really work together and share relevant information is not easy. What is missing are components that can be used in a wide variety of devices to make this possible. The OSAMI project will develop these components in a collaboration between industry, universities, local governments, and the European Union.

The good news is that one of the few decided parts of this project is the choice for OSGi. Looking at the problem domain this project is attacking, this is an obvious choice. The specifications are a standard in the market, adoption is high and growing. They give you device- and OS neutrality through Java. And last but not least, the OSAMI domain is close, if not identical, to the domain the OSGi was created for ten years ago.

Obviously, the problem of assembling larger applications out of smaller components is very hard, especially in a dynamic environment like the ones we live in. However, we have gained a lot of experience in those early days and I think we are ready today. The biggest threat I see is the size of the project and its organization. Each country has a local organization that handles the subsidies. Trying to develop components that will work together and will share some kind of architectural consistency will be a major challenge. My (admittedly limited) experience with European projects makes me a bit worried that local champions can focus on their own needs instead of developing a commons that will benefit us all. One of the key failures in a previous project was quite unexpected. It turned out that the participants in the projects never arranged the rights for the material that was created. At the end of the project, it was completely unclear who could do what with the results.

Another challenge will be the standardization of the services. It is quite easy to create an OSGi component that performs some function. However, to generalize and abstract that function in an OSGi service is hard work, I learned.

And not to forget, there are the always significant administrative duties involved in European projects.

So overall, this project is a big challenge but it is also a tremendous opportunity for the OSGi Alliance. In the next couple of years, a very large number of people will be developing an even larger number of components in several open source projects. This will be a significant boom to OSGi in almost any computing field.

I do hope the OSAMI project(s) will take the effort to align their activities with the OSGi Alliance and work to turn their efforts in OSGi Compendium services. This will require a significant effort from the OSAMI participants because the only way to get a service in the specification is to work on it in an OSGi Expert Group.

Anyway, I will closely follow the OSAMI project and report about its progress. I will do my best to liaison between the OSAMI organization and the OSGi Alliance so we can make this project a great succes.

Peter Kriens

P.S. If you want so more information about OSAMI, read a short overview of the German branch of the OSAMI project.

Wednesday, September 17, 2008

Impressive Press Release

If I am honest, I usually find press releases boring (Sorry Alisa). However, this time I must admit that the latest press release of the OSGi Alliance is surprisingly impressive. If you work with something on a daily basis, you often lose track of the progress that is being made, I was therefore pleasantly surprised when I saw the acclamations being made about OSGi by all the leading application servers vendors. I think one can call it progress if all the leading Java Enterprise Edition application servers have used OSGi as their foundation. In alphabetical order:
  1. IBM Websphere. They started in 2006 and aggresively moved their code on OSGi. Obviously it helped that IBM has committed itself to OSGi since day -1.
  2. Oracle WebLogic. Formerly known as BEA weblogic. BEA was one of the first companies public touting the advantages of OSGi, clearing the road for others.
  3. Paremus Infiniflow. Paremus has pioneered the use of OSGi in highly distributed application servers allowing the system to scale to unprecendented heights.
  4. ProSyst ModuleFusion. ProSyst is the key provider of OSGi technology in the embedded worlds but originated from the development of a J2EE server. They are now back in this market with an offering based completely on OSGi.
  5. Redhat JBoss. JBoss already worked with a microkernel approach but recognized the advantages of a standard two years ago.
  6. SAP Netweaver. Well, they are not yet based on OSGi, but they clearly see their future based on the OSGi specifications and are becoming more and more active in the OSGi Alliance.
  7. SpringSource Application Platform. The company that simplified Enterprise development with their Spring Framework decided to create their own offering in the application server market completely based on the OSGi specifications.
  8. Sun Glassfish. And last, but definitely not least, Sun decided to use OSGi in the JEE reference implementation Glassfish. They clearly take OSGi extremely serious nowadays since they also hired Richard S. Hall. It is so good to see Sun back at the OSGi Alliance.
Though not mentioned in the press release because they are not a member, there is also Jonas, an open source JEE implementation that that was arguably the first JEE implementation completely on OSGi. I guess that only leaves Geronimo struggling with modularity? Despite the interestying work that Glyn Normington did in creating an OSGi prototype two years ago.

As said, this list is impressive by any measure. It is a clear indication that the OSGi specifications are mature and robust. Application servers are highly strategic products for companies; no fortune 500 company bets the house on something that is not highly reliable. Even better, most people know how painful it can be to move non-modular code the strong modularity that the OSGi Framework enforces in runtime. The fact that the key software firms in our industry has made this move signals that the advantages of strong modularity are more than worth this pain.

What does this mean for application developers? Interestingly enough, several application platforms based on OSGi do not expose the OSGi APIs for application developers. The companies that really embrace OSGi are SpringSource, ProSyst, Paremus, and Jonas. IBM, Oracle, and Redhat use the advantages themselves but do not (yet?) allow their customers to use them. However, I expect (and hope) that this will change over time. Why? Because for the first time you can now create middleware libaries that can be deployed on all major application servers without having to worry about implementation differences. I expect this possibility to become too attractive to ignore in the next few years, but today, some of the major vendors exclude this possibility. We'll see what will happen.

It is kind of bizarre that a technology developed for home automation ten years ago now ends up as the state of the art foundation of the servers that run the web. However, there is no time to sit on our laurels. This is a major milestone on the road to building applications from components, the vision I have been chasing all my working life.

Peter Kriens

Monday, September 8, 2008

SPI in OSGi

If you search for OSGi on the net you will find lots of references to class loading problems. Many, if not most, of those problems are related to SPIs, or Service Provider Interfaces, a.k.a. plugins, a.k.a. extensions. The developer provides a collaborating mechanism for other developers that he has no direct connection with. An SPI usually consists of some interface that needs to be implemented by a service provider. The hard problem is linking that service provider's code into the main own code. Because the developers have no clue who will provide extensions, they can not just new an implemenation class. They need some mechanism that provides them the name of the implementation class so they can create an instance with Class.forName and newInstance.

One popular mechanism in the Java VM is the service model. In this model, a JAR can contain a file in META-INF/services that has the fully qualified name of the SPI class, usually a factory. When you the getDefault, or getInstance, method on the SPI class, it reads that file and gets the name of the implementation class. It then tries to load that class. However, this process is not well supported with an API and it is therefore sometimes hard to find that class, causing the developers to do class loader hacks. Hacks that tend to work in the anarchistic class path of the VM but that do not work in OSGi because of the modularity restrictions. (How can you load the proper class if all you have is a class name and no version information?) In several blogs I complained about doing these hacks to get extensibility, but I never showed how you could do an SPI model in OSGi.

A very popular way in OSGi to do SPIs is the white board pattern. The white board pattern means that providers just register a service and the SPI code just enumerates all these services. As an example, we create a little portal. This is a servlet that lists a number of HtmlFragment services on the left side, and when you click on their link, it will list the an HTML fragment on the right side of the page.

Disclaimer: the following code ignores error checking to focus on the extension mechanism. Please do not code like this in production systems ...

We start with the service definition. In OSGi, a service is usually defined in an interface. You can use a class but it is more flexible to use an interface. In this case we define the HtmlFragment interface.

package my.service;
import java.io.*;
import javax.servlet.http.*;
public interface HtmlFragment {
String NAME = "fragment.name";
String TITLE = "fragment.title";

void write(
HttpServletRequest request,
PrintWriter pw) throws Exception;
}
This interface defines properties for the name of the Html Fragment and the title of the Html Fragment. The name is the last part of the URL, the title is human readable. The write method is called when the fragment should write something to the screen. The parameters are passsed in an HttpServletRequest. With this interface we can write an example fragment. In good style, we create an Hello World fragment.

package my.fragment.hello;
import java.io.*;
import javax.servlet.http.*;
import aQute.tutorial.service.portal.*;

public class Component implements
HtmlFragment {
public void write(
HttpServletRequest request,
PrintWriter pw) throws Exception {
pw.println("Hello World");
}
}
The bnd code to run this (assuming you use declarative services) is:
Private-Package: my.fragment.hello
Service-Component: my.fragment.hello.Component;\
provide:=my.service.HtmlFragment; \
properties:="fragment.name=agent,fragment.title=Agent"

It should be obvious, that you could creat many different Html Fragment services, each providing their own content.

The next code we need is the portal code. This can be a servlet. You register a servlet with an Http Service. Declarative services makes this quite trivial. So this is all there is to the portal code:
package my.portal;

import org.osgi.framework.*;
import org.osgi.service.component.*;
import org.osgi.service.http.*;

public class Portal {
BundleContext context;

protected void activate(
ComponentContext context) {
this.context = context
.getBundleContext();
}

public void setHttp(HttpService http)
throws Exception {
http
.registerServlet("/portal",
new PortalServlet(context), null,
null);
}

public void unsetHttp(HttpService http) {
http.unregister("/portal");
}
}

Due to the needed HTML, the Portal Servlet is a bit bigger:

package my.portal;
import java.io.*;
import javax.servlet.http.*;
import org.osgi.framework.*;
import aQute.tutorial.service.portal.*;

class PortalServlet extends HttpServlet {
final BundleContext context;

PortalServlet(BundleContext context) {
this.context = context;
}
public void doGet(
HttpServletRequest request,
HttpServletResponse rsp)
throws IOException {
PrintWriter pw = rsp.getWriter();
try {
String path = request
.getPathInfo();

if (path != null
&& path.startsWith("/"))
path = path.substring(1);

pw
.println("Portal");
pw
.println("
Portal
\n");

ServiceReference found = null;
ServiceReference all[] = context.getServiceReferences(HtmlFragment.class.getName(), "(&(fragment.name=*)(fragment.title=*))");
for (ServiceReference ref : all ) {
String name = (String) ref
.getProperty(HtmlFragment.NAME);
String title = (String) ref
.getProperty(HtmlFragment.TITLE);

pw.printf(
"%s",
name, title);
if (name.equals(path))
found = ref;
}

pw.println("
");

if (found != null) {
HtmlFragment fragment = (HtmlFragment) context.getService(found);
fragment.write(request, pw);
}
pw
.println("
");
} catch (Exception e) {
e.printStackTrace();
}
}
}
That is all! Again, obviously no error checking but it demonstrates rather well how you can use the OSGi Service Registry to implement SPIs.

And did you realize this code was 100% dynamic?

Peter Kriens

Blog Archive