Running Eclipse applications on Windows 8

March 28, 2013 | 3 min Read

Reading the title, you might ask why this could be a problem. Good news: in most cases it isn’t. However it can be problem if you use native code in your Eclipse plug-in and run on an older version of Equinox (3.7.2 and earlier). This post describes the problem and possible solutions.

The problem

On older Windows versions, our Eclipse RCP/RAP application works fine. On Windows 8 however, the application does not start because one bundle is not resolved and results in the following error message:

!MESSAGE Missing host Bundle-NativeCode_0.0.0.

The problematic bundle references native libraries. There are different native libraries for different operating systems. OSGi defines a way to declare those dependencies, and makes sure that the right library is loaded, depending on the current operating system. According to the OSGi specification, we used the Bundle-NativeCode header in the MANIFEST.MF:

Bundle-NativeCode: helper.dylib; osname=macosx, helper.dll; osname=win32, helper.so; osname=linux

The expected behavior on any Windows version is that OSGi would try to load the helper.dll. This does not however, work on Windows 8.

The explanation

When OSGi is trying to resolve the bundle, it is searching for a library whose condition is fulfilled, i.e. at least one of the conditions must evaluate to true. The message above actually means that OSGi could not find a matching condition and therefore does not resolve the bundle.

As a condition, we have here the osname property. Its value is compared with the value of the system property org.osgi.framework.os.name which is usually filled by the Java VM. What makes things more complicated is the fact that Java might return different values for the same operating system. All (currently) known values are listed on this wiki page. Equinox solves the problem of multiple possible values with a mapping table which is maintained in file org/eclipse/osgi/framework/internal/core/osname.aliases of the bundle org.eclipse.osgi. As an example, for Windows 7 the row in the mapping table looks like this:

Windows7 “Windows 7” Win7 Win32 # Microsoft

This entry makes sure that a condition osname=Win32 even resolves if Java reports Windows7 as the operating system name.

The reason why this mechanism fails with our application is simple. We are using an old version of Equinox (3.7.2) whose mapping table does not contain a row for Windows 8 because it was not released at that time and it was not possible to anticipate which values the Java VM would provide. BTW, the row was introduced with the Juno release (3.8).

The solution

Basically there are three possible solutions:

  1. Upgrade to a newer Equinox version: probably the best solution. However, it is not a trivial change and is only possible if you can change the application.

  2. Add conditions to the manifest:

    Bundle-NativeCode: helper.dylib; osname=macosx, helper.dll; osname=win32; osname=Windows8; osname=Windows 8; osname=Win8, helper.so; osname=linux

    This change is much smaller and less intrusive, but quite ugly, and you still need to be able to change the application.

  3. Manipulate the system property: start your Java VM with the system property

  -Dorg.osgi.framework.os.name=win32

There is no need to change the application here, but you might compromise code which relies on the original OS name coming from the Java VM.

Problem solved, case closed - until Windows Blue comes out.