0

I have some jar file which is not osgi bundle. Let's call it starter.jar. And I run this starter this way: java -jar starter.jar. This starter starts felix framework:

Felix felix = new Felix(configMap);
systemBundle=felix.getBundle();

and after that installs and starts osgi bundles which export some services.

So starter is outside osgi container, however it has reference to systemBundle. Is it possible and normal (safe) to use some osgi services in starter.jar?

EDIT Now I know that this is possible, because I have working solution (the code from starter.jar):

BundleContext bundleContext=systemBundle.getBundleContext();
ServiceReference reference = bundleContext.getServiceReference(Temp.class.getName());
Object server = (Object) bundleContext.getService(reference);
Method method = server.getClass().getMethod("getString");
Object result=method.invoke(server);

I had to use reflection as I got classCastExceptions because of different classloaders. And final solution is rather ugly. Maybe someone will offer a better way. Or there is no way except via network socket?

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • You can add the package that contains the service interface to the system packages of the embedded OSGi container. In that case, you can use the service without reflection. – Balazs Zsoldos Jul 23 '16 at 17:51
  • @Balazs Zsoldos I will try. Seems to be very good idea. – Pavel_K Jul 23 '16 at 17:57

1 Answers1

2

There are two important rules that apply:

  1. The provider and consumer of a service must both import the API package (i.e. the package that defines the service interface) from the same export. This can be arranged in several ways. Either both provider and consumer import from a third API bundle... OR the provider can export the package and the consumer imports from it... or (rarely) the consumer can export the package and the provider imports it.

  2. The system bundle cannot import packages from ordinary bundles. It can only export.

The second rule means that when you want to communicate with services between the system bundle and ordinary bundles, the API package must be put on the classpath of the system bundle and exported using org.osgi.framework.system.packages.extra. Then the ordinary bundles import the package in the normal way. You must do it this way, irrespective of whether the system bundle is the provider or the consumer of the service.

Neil Bartlett
  • 23,743
  • 4
  • 44
  • 77