How to use the OSGi service from a web application?

I am trying to create a web application that will be launched from the OSGi HTTP service , this application needs to use another OSGi service (db4o OSGi), for which I need a link to BundleContext. I tried using two different approaches to get the OSGi context in a web application:

  • Save BundleContext Activatorin a static field of the class that the web service can import and use.
  • Use FrameworkUtil.getBundle(this.getClass()).getBundleContext()(as an thisinstance MainPage, a web application class).

I think the first option is completely wrong, but in any case I am having problems with class loaders in both cases. In the second, it calls LinkageError:

java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/felix/framework/ModuleImpl$ModuleClassLoader) previously initiated loading for a different type with name "com/db4o/ObjectContainer"

Also tried with Equinox, and I have a similar error:

java.lang.LinkageError: loader constraint violation: loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) previously initiated loading for a different type with name "com/db4o/ObjectContainer"

The code that throws the exception:

ServiceReference reference = context.getServiceReference(Db4oService.class.getName());
Db4oService service = (Db4oService)context.getService(reference);
database = service.openFile("foo.db");

An exception occurs in the last line, databaseclass is ObjectContainer, if I change the type of this variable to Object, an exception does not occur, but it is not useful as Object:)

Update . I tried to use other services instead of db4o, and they worked as expected. Maybe the db4o OSGi bundle does something weird when loading its own classes, or maybe I am not using it correctly. It also works if I use it from a non-web package.

+3
source share
3 answers

BundleContext ? , ( BundleContext ).

OSGi , : ) OSGi , , ) , OSGi Java 2 . , , .

0

100%, , , :

Thread currentThread = Thread.currentThread ();
ClassLoader origLoader = currentThread.getContextClassLoader ();

currentThread.setContextClassLoader (Db4oService.class.getClassLoader ());

ServiceReference reference = context.getServiceReference(Db4oService.class.getName());
Db4oService service = (Db4oService)context.getService(reference);
database = service.openFile("foo.db");

currentThread.setContextClassLoader (origLoader);

, OSGi , (Db4oService) .

0

Using the felix server environment and web services on the quay, you can easily use any OSGi services in any web services.

First you need to enter ServletContext in your web service so that you can access the OSGi context by calling servletContext.getAttribute ("osgi-bundlecontext"). The result is your OSGi-bundle context.

Please find a complete example at http://blog.meyerdaniel.ch/2012/08/accessing-osgi-services-from-servlets.html

0
source

Source: https://habr.com/ru/post/1738995/


All Articles