JFX as an OSGi service?
Stephen Winnall
steve at winnall.ch
Thu Feb 18 17:33:37 UTC 2016
Hi Erik
Thanks for this - it makes sense.
I was wondering about
1) getting the sub-class of javafx.application.Application to register itself at runtime as an OSGi service; or
2) trying to create a ServiceFactory that creates an instance of javafx.application.Application (perhaps decorated or proxied); or
3) cloning javafx.application.Application and making a version compatible with declarative services.
Your approach is no. 4 and has the advantage that it is known to work!
It seems a pity that JavaFX has such a closed/proprietary approach to starting a javafx.application.Application.
Cheers,
Steve
> On 18 Feb 2016, at 17:40, Erik De Rijcke <derijcke.erik at gmail.com> wrote:
>
> Hi Stephen,
>
> We use JavaFX in an OSGi container, as a service component, in production, so it's perfectly possible.
>
> However there are a few gotcha's you need to take into account (I can not c/p the code for obvious reasons...) which makes using it in osgi... quite horrible :)
>
> When triggering a javafx application in say, your component activate method (as we do), you're actually creating a new javafx application instance, a whole new identical object but without any scr dependency injection.
>
> This is problematic as your osgi object has all the dependencies injected from the osgi container while the javafx object does not.
>
> What we do is this: in our activate we copy all our osgi dependencies, as well as our ourself (this) to static fields, this makes them accessible in the start method of the javafx object. When start is called, we store the javafx object in a static field (which we access by calling 'this' in the start method). We now have access to all dependencies and both objects at any time. Now it's just matter of delegating calls from one instance to another if needed...
>
> btw, don't forget to call launch in a separate thread in your activate, else you'll block your bundle activator thread indefinitely oh *and* sync (block) your osgi component activate until the start method of your javafx has finished else your component will announce itself activated while javafx is still busy initializing.
>
> Oh another gotcha, try to avoid using Platform.runLater, as that will only work *after* your application component was activated, instead make a non static runLater method in your osgi javafx application component and use that. That will ensure that javafx was initialized before invoking any platform run later.
>
> Unfortunately javafx has a lot of static { Platform.RunLater} calls spread out in different classes, so don't try to load those classes before your javafx application was started... OUCH!
>
> Didn't I say it was hairy and messy? JavaFX and OSGi is quite a bad match unfortunately.
>
> On Thu, Feb 18, 2016 at 3:38 PM, Stephen Winnall <steve at winnall.ch <mailto:steve at winnall.ch>> wrote:
> I am trying to make JavaFX 8 work with OSGi Declarative Services. My preferred solution would be to instantiate javafx.application.Application as an OSGi service.
>
> As I understand it, there are two ways of activating JavaFX:
>
> 1) sub-class javafx.application.Application or
> 2) call javafx.application.Application.launch()
>
> However, both of these approaches give me a POJO, which makes interaction with OSGi services and bundles very difficult.
>
> Is there a “proper” way of starting JavaFX as an OSGi service? If not, are there any plans to support this?
>
> Regards,
> Steve
>
More information about the openjfx-dev
mailing list