Sunday, May 25, 2008

More on the "OSGi hype"

I’ve seen more and more people talking about OSGi lately. Some are saying that we are going through “OSGi hype”…

Well, I’ll talk about the OSGi hype here too :)

OSGi is being around for almost ten years. Maybe it gained (more) momentum after Eclipse adopting it since version 3. I’m not sure, I have no "authority" to say that. That's just what I think as an outsider.

A non-exhaustive list of OSGi advantages: no more classpath hell, modules life cycle, dynamic updates with no application reboots, package visibility, decoupling through services.

Several important organizations are seeing OSGi’s value and are investing on it. This guy posted a list of applications using OSGi. We can add Apache Sling , Apache ServiceMix and Project Fuji to that list too, as well as Glassfish. I've worked as part of the team that developed a now extinct product built on top of OSGi. There must be a lot of other not so popular stuff built with OSGi.

Maybe some recent events caused all this hype:

  • JOnAS 5 released as the first (I guess it was the first one) JEE application server to run on top of OSGi.
  • Recently we’ve seen Glassfish using it.
  • JBoss is talking about OSGi.
  • BEA (now Oracle) is using OSGi in its microservice architecture.

I guess OSGi has become the de facto module system for Java. It seems that JSR 277 has a risk of falling into oblivion when it becomes released if it does not converge with OSGi. Since so many important announcements about OSGi adoption are taking place, we are seeing this “OSGi hype”.

In my opinion, this is not hype. It is industry evolution. But those that still do not get it may see it only as hype.

Technology hypes may sometimes lead to some naïve decisions like “let’s use it because it’s a cool trend and everybody is using it. It's a new trend”. Maybe that was a naïve example too...
Before choosing to use stuff like OSGi try to evaluate if it fits your needs. Get to know it better. Maybe taking a look at the docs in the OSGi alliance website or looking for tutorials. Decisions like this involve the architecture of your project.

Whoever tries to use OSGi must be careful with the sometimes steep learning curve. Try to take advantage of existing component models (OSGi declarative services, Service Binder, Spring DM, iPOJO) that handle hard dynamic aspects, service location, dependency injection, and do all the dynamic voodoo magic. There was a time when all that stuff needed to be made by hand. You don’t need to do that anymore.

There is some stuff that is painful in the beginning like “bundlizing” a jar. But constructing an OSGi compliant manifest may be simplified by automated stuff like a bundle plugin for maven. Well, there is plenty of stuff (like here) to minimize efforts concerning OSGi development.

I'm away from the market for almost a year and started (or continued, if you will) to do research that involves OSGi. Each time I see news about its adoption in industry I get even more motivated about my choice.

Even if you don’t buy the idea or if it is useless for you, it is worth taking a look. OSGi is not just a buzzword. Try to use it not because it is hype, check its benefits first.

Wednesday, May 14, 2008

Do you know weak references? Have you ever used them?

I’ve been using a lot of weak references lately. A couple of years ago I’ve read a blog entry that said that a lot of experienced Java developers did not know what they were. I’m glad I already knew it at the time I’ve read that :)

I won’t go into details of weak references. I’ll just say that an object is not prevented to be garbage collected if it only has weak references pointing to it. You can get a nice overview here.

In my current project I’m tracking garbage collection of special types of objects by using weak references. Maybe in another post I’ll provide more info on that.

Throughout my career I’ve used that nice resource of Java a few times. The most important ones that I can remember are:

  • Weak Listeners
  • Memory Sensitive Caches

Weak Listeners

Memory leaks are a painful problem that sometimes we don’t have a clue how to find them. I’ve worked in a desktop project where we had lots of instantiations of GUI panels, models, etc. That implied in a bunch of model listeners, property listeners, and so forth. We had a major memory leak due to a simple problem in most of the panels: objects from each created panel were being added as a listener of the model, but after the panel was discarded they did not remove themselves from the listeners list of the model. So, they kept being reference by the listeners list on the model and could not be garbage collected.

A naïve example tries to illustrate that:

public void setActivePanel() {
MyPanel thePanel = new MyPanel();
ApplicationModel.getInstance().addXYZListener(thePanel);
this.activePanel = thePanel;
}

public void releaseActivePanel() {
this.activePanel = null;
this.clearSelection();
}

One solution was to provide a way to unsubscribe "thePanel" from the XYZListener list:

public void releaseActivePanel() {
ApplicationModel.getInstance().addXYZListener(this.activePanel);
this.activePanel = null;
this.clearSelection();
}

But.... you could also use weak references. They would avoid such problems. At the time I found good stuff that I’ve used as a reference.

The only issue that I see in his solution is that we may have sometimes a bunch of empty WeakPropertyChangeListeners (pointing to null) when the referred object is GC’d. He provides a lazy approach for clean up. However, if you use your own ReferenceQueue you can provide a thread that once in a while polls the queue and does the sweeping of listener lists. Or also you can use a WeakHashMap which does the dirty work of clean up.

Memory sensitive caches

There are several caching strategies (e.g. LRU, MRU) but this one is very simple. It caches everything, but when the system runs out of memory the cache is cleaned up.

Depending on the memory footprint of your system this strategy may be useless and your cache will not work really well.

This memory sensitive cache relies on SoftReferences. They are special types of WeakReference which hang around for a while.

The following class is not an optimal implementation of a cache, but it works…

public class ImageCache {
private HashMap<String, SoftReference<ImageIcon>> map = new HashMap<String, SoftReference<ImageIcon>>();
private static final String IMAGE_FOLDER = "/images/";

public ImageIcon getImage(String imageFile) {
ImageIcon icon = null;
if (map.containsKey(imageFile)) {
icon = map.get(imageFile).get();
if (icon == null) {
icon = cacheImage(imageFile);
}
} else {
icon = cacheImage(imageFile);
}
return icon;
}
private ImageIcon cacheImage(String imageFile) {
ImageIcon icon = new ImageIcon(this.getClass().getResource(
imageFile));
map.put(imageFile, new SoftReference<ImageIcon>(icon));
return icon;
}
}
Another cool stuff that can be done (although I've never done it in a "real life" project as I did with the other stuff) is to provide an alternative way to finalization using PhantomReferences. You can use them combined with a ReferenceQueue to provide your own finalization mechanism avoiding the error-prone finalize method. You could write your own finalizer thread :)

There is a good reference here.

I guess that it for the moment.