Posts Tagged ‘Equinox’

Friends of yours? Using x-friends in Equinox to loosen the API restrictions for some plugins

Tuesday, May 25th, 2010

In Defining provisional API in Equinox I discussed how to mark your API as internal / provisional. But what if your plugin has a close friend which should be allowed to use this API without restrictions? Even in the plugin world some plugins are sometimes closer to each other.

This can be achived by the x-friends directive. Which can be added via the some editor which added the x-internal flag.

This should result in the following MANIFEST.MF.


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Provider
Bundle-SymbolicName: de.vogella.osgi.xinternal.provider
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: de.vogella.osgi.xinternal.provider;x-friends:="de.vogella.osgi.xinternal.consumer"

By this setting the package de.vogella.osgi.xinternal.provider can be used by the plugin “de.vogella.osgi.xinternal.consumer” without restrictions but is mark as “x-internal” for all other plugins.

Choose your friends wisely. ;-)

I didn’t mean it like this – Defining provisional API in Equinox

Thursday, May 20th, 2010

OSGi is very strong in defining API contracts. In each bundle you can decide this which packages are exported and which can be used by other plugins.

But what if you want to make your classes usable to other but don’t want to to make it final API, so that you can change it later after the first consumer have tried using it. You want to export it, but you want to put a warning sign out there to tell everybody that this is not fixed API.

Meet the x-internal extension of OSGi in Equinox. This extension allows you to export you API but mark it as internal so that the consumer knows that he is using an API which may be changed later. To test this out create a new plugin project “de.vogella.osgi.xinternal.provider” using no template. Implement the following class.

package de.vogella.osgi.xinternal.provider;

public class Hello {
	public String getHello(){
		return "Hello";
	}
}

Switch to the MANIFEST.MF, select the tab Runtime. Export you package, select it and select under “Package Visibility” the flag “hidden from all plug-ins except”.

This should result in a MANIFEST.MF like this.


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Provider
Bundle-SymbolicName: de.vogella.osgi.xinternal.provider
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: de.vogella.osgi.xinternal.provider;x-internal:=true

To test you export create a new plugin project “de.vogella.osgi.xinternal.consumer”. Define in MANIFEST.MF a dependency to “de.vogella.osgi.xinternal.provider”. Define a class which uses the class “Hello.java”, e.g.

package de.vogella.osgi.xinternal.consumer;

import de.vogella.osgi.xinternal.provider.Hello;

public class Test {
	public static void main(String[] args) {
		Hello hello = new Hello();
		System.out.println(hello.getHello());
	}
}

Depending on your preference settings you receive either an info, or a warning or an error.b

The Eclipse platform uses this directive quite ofter for API which should not be considered as public API. You can also make your API consumer aware if the API is rock solid or if the consumer should be careful in using it.


Switch to our mobile site