2

I am currently writing an application that runs in an OSGi environment.

For the visualization part I am using JavaFX. Each UI element is a dockable view that extends BorderPane. Its content is described using the fx:root element in a fxml file. Some of those UI elements need to access services within the OSGi container (for example a button in a view might trigger the save action which needs a reference to the PersistenceService).

What is the best way to achieve this?

The UI elements are automatically generated by a framework that I use. the only way to access services are the BundleActivator or the static method FrameworkUtil.getBundle().

My approach was to use the static utility method but after some more reading on the net I realized that you normally do not want to code against OSGi itself.

The other solution is using the scr annotations provided by Apache Felix. Marking the UI elements as @Component and referring each needed service via @Referencewould work. But is this good practice? Should I annotate them? I always though the classes referred by @Component are managed by OSGi itself and will always be instantiated by OSGi.

Jérémie B
  • 10,611
  • 1
  • 26
  • 43
SirWindfield
  • 117
  • 2
  • 8

1 Answers1

3

First of all, if you want to declare/reference your services directly in Java Code, you should consider using ServiceTracker to avoid many problems with the nature of ServiceReference.

SCR Annotations are a good way to do it, another (which is more friendly with legacy projects which already use Spring or Blueprint) is to use directly Blueprint or if you want spring functionality spring osgi compendium and inject the beans <service> and <reference> with your standard annotations @Named/@Component, @Inject/@Autowired.

The main benefit with this last option is that containers such as Karaf can automatically load your spring configuration (considering it is in META-INF/spring/*.xml files) and register/reference services.

You can for example easily implement whiteboard pattern with blueprint reference-list and track all the services exposed for a specific interface.

For the annotations, I do think the debate is more about "annotations vs config files" than related to OSGi. I personally think it's a matter of choice between intrusive annotations that bind your implementation with other APIs, while other solution (such as an external .xml configurations files, would be less intrusive). But in the end, it's more a large discussion than OSGi. See this other thread.

Community
  • 1
  • 1
Jonathan Schoreels
  • 1,660
  • 1
  • 12
  • 20
  • Thank you! The ServiceTracker looks good. Still, that doesn't answer my last question. The ServiceTracker would solve this without any doubts but I am still curious if annotating UI elements is good practice or not. But Spring can just inject beans right? – SirWindfield Mar 15 '16 at 22:30
  • 2
    It's 2016, proposing to use directly a ServiceTracker or Spring DM instead of Declaratives Services doesn't seem to be a good advice, at least from my point of view ;-) – Jérémie B Mar 15 '16 at 22:30
  • 2
    I agree with @JérémieB. ServiceTracker is very low-level, it couples your code directly to OSGi, it is hard to use correctly and is hard to test. Please use DS with the standard annotations. – Neil Bartlett Mar 16 '16 at 09:47
  • Sorry if I gave the idea that I prefer ServiceTracker or Spring DM than SCR/DS. I edited to specify that the option available to use Spring DM or Blueprint is a solution when you have to deal with legacy projects which relied on Spring/Blueprint. – Jonathan Schoreels Mar 16 '16 at 10:11
  • 2
    Thanks. BTW I would avoid the legacy SCR Annotations from Felix and use the standard ones from the OSGi specification. – Neil Bartlett Mar 16 '16 at 11:13
  • Are there some limitations on what classes I can put the component annotation on? I mean, I can literally use it on any class that somehow needs a reference to an osgi service. Why are people just not doing it? – SirWindfield Mar 16 '16 at 22:13
  • 1
    The limit is that DS owns the class and its lifecycle. This is necessary because if the service you inject goes away and you have a mandatory reference, your component has to go away too. – Neil Bartlett Mar 17 '16 at 00:33