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

Monday, August 25, 2008

Why Services are Important

Many people choose OSGi because it provides them with far superior class loading functions than plain Java. Some even say that OSGi is class loaders on steroids. However, viewing OSGi from this perspective is like building a car that looks like a horse carriage with engine. Taking full advantage of OSGi requires the use of services, however, the service model is much more enigmatic for most people than class loading. A good friend of mine, Niclas Nilsson, who visited me last week told me a story about how people view software languages in a very subjective way. If the languages they are familiar with do not have a specific feature, then they have a tendency to view this feature as unimportant and consider them (unnecessary) syntactic sugar. For example, few Basic programmers missed objects in the nineties.
I think services are a bit like this. There are millions very experienced Java programmers that build impressive libraries and applications using class loaders as extension mechanisms. There is a wealth of knowledge and experience. In contrast, OSGi services implement a concept where one cannot find a comparable mechanism in plain Java, nor in other languages/environments.

Why are services then so important if so many applications can be built without them? Well, services are the best known way to decouple software components from each other. And, I assume that you are aware of the many advantages that decoupling gives you in almost any aspect of software development.

One of the most important aspects of services is that they significantly minimize class loading problems because they work with instances of objects, not with class names. Instances that are created by the provider, not the consumer. The reduction of the complexity is quite surprising. Simple example is Hibernate; most of the class loading problems in Hibernate are caused by the fact that the configuration is done in XML files. Working with Class instances and instances of those classes make most problems go away.

What kind of problems do you have with the class names? Well, first you have to configure it. This means that if you want to change the implementation, you must not only edit some (hard to read) XML or properties file, you must also make sure that the right JAR files are on your class path. In a service based system, you only install the proper bundle. Look at the 'interesting' world of logging in Java. Most logging subsystems handle their extension needs with class names. This requires having property or XML files in the right place and requires you to have the right logger implementation on your JAR path. In an OSGi world, the only thing you have to do is install an implementation of the log service and everybody uses that log service. As Richard Hall always says: 'The set of installed bundles is your configuration.'

Not only do services minimize configuration, they also significantly reduce the number of shared packages. In Class.forName based system you need to be able to see all possible implementation classes. In a service based system, you only need to see the package in which the service is defined. And the best package is one that is not shared.

To be honest, after working for many years with OSGi I really had to get used to the idea that one could also share packages with implementation code; before R4 OSGi was only intended to share service packages. It seemed such a bad idea.

Sharing implementation classes is almost always bad because it makes bundles extremely dependent on each other. The reason we added all those powerful class loading mechanisms was not for them to be used in new designs, their primary purpose was to ease conversion of existing applications.

And last not least: versioning. Class.forName must fundamental flaw is that the only parameter is a string for the class name. In complex systems there will be multiple classes with the same name. This confusion is completely absent in a service based system because service objects are already correctly wired up.

However, I guess there is no escape to Niclas' story. If you have never built a real system with services it is hard to see the advantages and it is easy consider them as an extra without a lot of value. But, maybe this blog can give you the push to start using services in real designs and find out how surprisingly powerful this very simple concept is. Let me know!

Peter Kriens

Tuesday, August 5, 2008

Classy Solutions to Tricky Proxies

Though the quest for reusable systems is the guiding principle in my life, I only recently start to understand the reason for some of the mechanisms in Spring. For example, I start to see that the whole Aspect Oriented Programming (AOP) business is not about aspect oriented programming, but it is about hammering an existing code base into its intended slot. Unfortunately, some of the slots are square while the code bases are quite round. Therefore, proxying is an important aspect of developing a system by making a round object look square, or vice versa.

The bad news is that OSGi is not making this easier. The OSGi framework was designed with green field applications in mind that would follow proper modularity rules and communicate through services. In a perfect OSGi world, bundles are highly cohesive and are coupled through their services. In the real world, class loaders are (ab)used for configuration and ad-hoc plugin systems. Some of those problems are quite complex.

Today, I was asked about the following problem.

A company is using Spring. One of their bundles referred to a service that another bundle had registered. Spring has decided that services are too jumpy, so they proxy the service object for their clients and add some mixins in the proxy that handle the situations when a service goes away (Spring also adds some other mixins).

Creating a proxy is class loader magic. You take a set of interfaces (the mixins) and generate the byte codes for a class that implements all these interfaces. The implementation of the interface methods forwards the call to a handler object using the object, the method that was called and the arguments.

If you generate the byte codes for a class, you need to define this class in a class loader and this is where the modularity comes into play. In a traditional Java application you can just take the application class loader and define this new class in this class loader. The application class loader usually has full visibility. In a modular system, however, visibility is restricted to what you need to see. In OSGi, the imported packages are all a bundle can see (at least, when you want to work modular and not use dynamic imports buddy class loading).

The catch is that the proxy requires access to all the mixin classes. However, some of these mixin classes come from one bundle, and some come from another bundle. There is likely no class loader that can see both bundle class spaces unless that bundle specifically imports the correct interfaces. However, if a client bundle gets one of his objects proxified, then he has no knowledge of the mixins (that is the whole idea). It would be fundamentally wrong to import the interface classes while he is oblivious of them. However, the bundle that generates the proxy might know the mixin classes but it is unlikely it knows the classes of the target object. If the proxy generator was implemented as a service (as it should be) then there would even be 3 bundles involved: the proxy generator, the bundle needing the proxy, and the client bundle.

Spring solved this problem with a special class loader that chained the class loader from the client bundle together with the class loader of the Spring bundle. They made the assumption that the Spring bundle would have the proper imports for the mixin classes it would provide and the client bundle would have knowledge of the proxied object's classes.

So all should work fine? Well obviously not or I would not write this blog.

The generated proxy class can see the Spring bundle with the interface classes and it can see the all the classes that the client bundle can see. In the following picture, the client bundle imports the service interface from package p, but it does not import package q which is used in package p. If you create a proxy for a class in package p, it will need access to package q, and the client bundle can not provide this.



For example, assume the following case:

javax.swing.event.DocumentEvent de =
(DocumentEvent) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class<>[]{DocumentEvent.class}, this );

The DocumentEvent is from the javax.swing.event package. However, it uses classes from the javax.swing.text package. Obviously the bnd tool correctly calculates the import for the DocumentEvent class. However, when the generated proxy class is instantiated, it will need access to all the classes that the DocumentEvent refers to: the super class, classes used as parameters in method calls, exceptions thrown, etc. These auxiliary classes are crucial for the DocumentEvent class, but they are irrelevant for the client bundle, unless these classes are actually used in the client bundle, where they would be picked up by bnd.

So, if the client bundle does not import javax.swing.text then you will get a ClassDefNotFoundError when you try to instantiate the proxy class. This error gets generated when the VM sees the reference to class in the javax.swing.text package and tries to load it through the proxy class' class loader (that is why this is an error, it happens deep down in the VM).

To be specific, this is exactly as it should be in a proper modular system. The client should not be required to import classes that it does not need. The onus is on the proxy generating code to do it right.

Fortunately, the solution is not that hard but it highlights how easy it is to make the wrong assumption, believe me, these Spring guys are quite clever.

Just take a step back and look at the problem.

Do we need visibility on the bundle level here? Look at the information given to the proxy generator: a set of mixin classes. It does not really matter from what bundle these interfaces classes come from; the class loader that we need must be able to see each of the interface classes class loaders. By definition, those class loaders can see the right class space.

So instead of chaining the bundle class loaders, the problem can be solved by having a class loader that searches each of the class loaders of the used mixin classes.

For the Advanced


The sketched model is too simplistic because there is the cost of a class loader per generated proxy. Even though enterprise developers seem to live in a wonderful world where memory is abundant, as an old embedded geezer such abuse of class loaders worries me. Though it is possible to use a single combined class loader by keep adding the required class loaders but this raises the question of life cycle. Such an über class loader would pin an awful lot of bundle class loaders in memory and it will be very hard to not run into class space consistency problems because over time this class loader will see all class spaces. That is, this approach brings us back to all the problems of today's application servers.

I have not tried this, but the solution is likely to make the proxy generator service based. Not only will this make it easier to plugin different generators, it also means that the generator is bundle aware. It can then create a combining class loader for each bundle that uses the Proxy Generator service. This class loader will then be associated with the class space of that bundle and should therefore not be polluted with classes from other class spaces. In the Spring case, this would be the client bundle, not the spring bundle. The reason is, is that the spring bundle could be used from different class spaces.

However, the proxy generator must track any bundle that it depends on. That is, it must find out which bundle's export the interface classes and track their life cycle. If any of these bundles stop, it must clear the client's combining class loader and create a new one when needed. This will allow the classes from the stopped bundle to be garbage collected.

Peter Kriens


For the hard core aficionados, some code that demonstrates the problem:

First a base class that acts as activator. This base class calls a createProxy method in the start method. This is then later extended with a proxy generation method that fails and one that works ok.


package aQute.bugs.proxyloaderror;
import java.lang.reflect.*;
import javax.swing.event.*;
import org.osgi.framework.*;

public abstract class ProxyVisibility implements BundleActivator,
InvocationHandler {

public void start(BundleContext context) throws Exception {
try {
DocumentEvent de = createProxy(this, DocumentEvent.class);
System.out.println("Succesfully created proxy " + de.getClass());
} catch (Throwable e) {
System.out.println("Failed to create proxy" + e);
}
}

public void stop(BundleContext context) throws Exception {
// TODO Auto-generated method stub

}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}

abstract protected T createProxy(InvocationHandler handler,
Class primary, Class... remainder);

}


The following class uses the base activator but uses only the client bundle's class loader. Trying to create the proxy will therefore fail because this class loader can not see the javax.swing.text package.


package aQute.bugs.proxyloaderror;
import java.lang.reflect.*;

public class ProxyLoadError extends ProxyVisibility {

@SuppressWarnings("unchecked")
public T createProxy(InvocationHandler h,
Class primary, Class... others) {

Class parms[] = new Class[1 + others.length];
parms[0] = primary;
System.arraycopy(others, 0, parms, 1, others.length);

return (T) Proxy.newProxyInstance(getClass().getClassLoader(), parms,
h);
}
}


And at last, the solution. The following class extends the base activator and creates a proxy that uses a Combined Class Loader. This loader traverses all the class loaders of the mixin classes.


package aQute.bugs.proxyloaderror;
import java.lang.reflect.*;
import java.lang.reflect.Proxy;
import java.net.*;
import java.util.*;

public class ProxyLoadOk extends ProxyVisibility {

@SuppressWarnings("unchecked")
public T createProxy(InvocationHandler h, Class primary,
Class... others) {
CombinedLoader loader = new CombinedLoader();

Class parms[] = new Class[1 + others.length];
parms[0] = primary;
System.arraycopy(others, 0, parms, 1, others.length);
for (Class c : parms) {
loader.addLoader(c);
}

return (T) Proxy.newProxyInstance(loader, parms, h);
}

static class CombinedLoader extends ClassLoader {
Set loaders = new HashSet();

public void addLoader(ClassLoader loader) {
loaders.add(loader);
}

public void addLoader(Class clazz) {
addLoader(clazz.getClass().getClassLoader());
}

public Class findClass(String name) throws ClassNotFoundException {
for (ClassLoader loader : loaders) {
try {
return loader.loadClass(name);
} catch (ClassNotFoundException cnfe) {
// Try next
}
}
throw new ClassNotFoundException(name);
}

public URL getResource(String name) {
for (ClassLoader loader : loaders) {
URL url = loader.getResource(name);
if (url != null)
return url;
}
return null;
}
}

}

Monday, August 4, 2008

Sun Hires Richard Hall

It took sometime but yesterday it was official: Sun has hired Richard Hall in the Glassfish team! This is good news for Richard, who was looking for just a position like that, Sun, who can clearly use the expertise on OSGi that Richard as one of the foremost OSGi experts provides, Apache Felix because this means that Richard will be able to spend more time on this project, and also good news for the OSGi Alliance that will have one of its key expert group members represent Sun. Rarely is a change positive in so many ways.

I look forward to continue working with Richard in his new role. I hope that Richard's role will mean that Glassfish will become one of the key players in the next OSGi release, they clearly have the experience to match. Though it will be interesting to find out what happens in JSR 277 because Richard is currently an independent member. Will he continue to participate (though participate is a big word with the activity in the last year) or will he be able to actively work in that group (and get the long overdue EDR2 out)? That is still a question mark.

I wish Sun and Richard a very happy and fruitful cooperation and hope to be able to work with Richard for a long time.

Peter Kriens