Equinox, chose service implementation at runtime [message #1693708] |
Mon, 27 April 2015 13:30  |
Eclipse User |
|
|
|
Hello,
I'm working on a E4 application to control electronic boards. The application can only control a single board instance at a time, but I want to offer support for multiple boards without providing multiple versions of the compiled product/app (the user may have to restart the app to properly reload the bundles).
I'm using declarative services to implement a controller service for each board.
Is there any way to chose the implementation at runtime ?
I've been searching for weeks with no result. I'm open to almost anything :
- Lifecycle hook ?
- Bundlecontext registration filter ?
- Dynamic bundle loading ?
-... Anything else ?
I tried :
Bundle b = context.installBundle( location );
But this leads me to some stack trace and I still have to register the services manually (even though I have an OSGI component inside)
org.osgi.framework.BundleException: Error while renaming bundle file to final location: ....\.metadata\.plugins\org.eclipse.pde.core\MyApp.product\org.eclipse.osgi\187\0\bundleFile
at org.eclipse.osgi.storage.Storage.getContentFile0(Storage.java:765)
at org.eclipse.osgi.storage.Storage.getContentFile(Storage.java:741)
at org.eclipse.osgi.storage.Storage.install(Storage.java:506)
at org.eclipse.osgi.internal.framework.BundleContextImpl.installBundle(BundleContextImpl.java:146)
at org.eclipse.osgi.internal.framework.BundleContextImpl.installBundle(BundleContextImpl.java:139)
at org.myapp.core.internal.MyAppCoreActivator.start(myAppCoreActivator.java:34)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:771)
at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:764)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:721)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:936)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:319)
at org.eclipse.osgi.container.Module.doStart(Module.java:571)
at org.eclipse.osgi.container.Module.start(Module.java:439)
at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:454)
at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:531)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:324)
at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:320)
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:395)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:345)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:337)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:160)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:568)
at org.eclipse.equinox.internal.ds.model.ServiceComponent.createInstance(ServiceComponent.java:493)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.createInstance(ServiceComponentProp.java:270)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:331)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
at org.eclipse.equinox.internal.ds.Resolver.buildNewlySatisfied(Resolver.java:473)
at org.eclipse.equinox.internal.ds.Resolver.enableComponents(Resolver.java:217)
at org.eclipse.equinox.internal.ds.SCRManager.performWork(SCRManager.java:816)
at org.eclipse.equinox.internal.ds.SCRManager$QueuedJob.dispatch(SCRManager.java:783)
at org.eclipse.equinox.internal.ds.WorkThread.run(WorkThread.java:89)
Please help (maybe with technical snippets or link).
Thank you,
[Updated on: Mon, 27 April 2015 14:34] by Moderator
|
|
|
|
|
|
|
Re: Equinox, chose service implementation at runtime [message #1693975 is a reply to message #1693727] |
Wed, 29 April 2015 12:53   |
Eclipse User |
|
|
|
Thomas Watson wrote on Mon, 27 April 2015 22:15I don't understand why you would not use configuration admin to configure your target filter for selecting the service in DS. DS should have built-in support for configuring such things with configuration admin.
Correct me if I'm wrong, but with the ConfigAdmin, it is up to the consuming service to explecitely mention which implementation it wants to use, right ?
In this case, it won't work for me, be cause I already have some view that are designed to run with the interface of the service (ie, any implementation will work transparently, but only one at a time).
The other services that requires the implementation already consume a sub interface of the desired service.
Sorry, if I'm not very clear, english is not my native language 
|
|
|
Re: Equinox, chose service implementation at runtime [message #1694303 is a reply to message #1693975] |
Mon, 04 May 2015 05:23  |
Eclipse User |
|
|
|
When calling the injector for the service injection with the @Reference annotation, can the "target" be dynamic ?
@Reference(target="(type=really)")
GreatService greatService;
I think I'll will create a targetBoard property in each service using the service properties and the search the service by doing a
String targetBoard = ... // Find the target board for the application
String filter = "(targetBoard=" + targetBoard + ")";
ServiceReference[] serviceReferences = bundleContext.getServiceReferences( IBoard.class, filter);
|
|
|
Powered by
FUDForum. Page generated in 0.08136 seconds