JFX as an OSGi service?
Stephen Winnall
steve at winnall.ch
Sun Feb 21 19:22:54 UTC 2016
I’ve now got a subclass of javafx.application.Application that runs as an OSGi service and references other OSGi services under Java 8SE. I’ve tried to document it on Github (see https://github.com/winnall/OSGiJavaFXUsage) for the benefit of posterity.
Let me know if there are any mistakes or improvements required in the - sparse - documentation. I’m also not very good at Git :-(
Thanks to Erik de Rijcke, Maurice, Anirvan Sardar and Kevin Rushforth for their comments, all of which guided me - bouncing off the walls - to the goal.
Steve
> On 20 Feb 2016, at 20:37, Erik De Rijcke <derijcke.erik at gmail.com> wrote:
>
> This way only the app will be accessible by other components through the service registry. The app itself can not have any @reference because it it is javafx itself that instantiates the app object and not the osgi declarative services framework (which also takes care of injecting your dependencies).
>
> The way to work around this in java8 is to take the approach I describe, as far as I know that is the only workaround to get scr and javafx glued together.
>
> In javafx 9 this would be fixed by having your service component implement runnable and use the api described by kevin, as you can reuse the object created by the osgi framework.
>
> On Sat, Feb 20, 2016 at 3:27 PM, Maurice <info at cuhka.com <mailto:info at cuhka.com>> wrote:
> That is why the bundle activator creates a bundle-singleton of itself, that way the app can access the OSGi world. In my case to register itself as a service.
>
>
> @Override
> public void start(Stage primaryStage) throws Exception {
> ....
> primaryStage.show();
>
> Dictionary<String, ?> properties = createDictionary();
> BundleContext bundleContext = UdooActivator.bundleActivator().getBundleContext();
> bundleContext.registerService(com.cuhka.home.application.Application.class, this, properties);
> }
>
> Maurice.
> Op 20-02-16 om 15:08 schreef Stephen Winnall:
>
> Hi Maurice
>
> I have done something similar, but it has the following drawback in my view: the class launched (Udoo15App in your case) does not run under OSGi control, so it has no access to OSGi bundles or services, nor is it accessible by them. If you don’t need that, you're OK. But I need that class to be part of the OSGi world because other bundles/services are going to add parts to the UI as they are instantiated.
>
> Steve
>
> On 20 Feb 2016, at 14:33, Maurice <info at cuhka.com <mailto:info at cuhka.com>> wrote:
>
>
> For my OSGi based JavaFX solution on the Udoo Quad (ARM based Linux) I created a service that publishes the application in the context.The application does as little as possible. It sets up the primary stage as fullscreen and puts a stackpane in it. Initially the stackpane displays a 'boot logo', until the actual desktop bundle is started and registered with the application. Note that you have to start the application on a separate thread, as the thread will be blocked.
>
> On Java 8 this means that although the application bundle can't be updated in a running OSGi container, but that is why the desktop exists. On startup it registers itself, and thus the application content, with the application, and when it is stopped it removes the content from the application. The application has thus rarely to be updated itself.
>
> Regards,
> Maurice.
>
>
>
> public class UdooActivator implements BundleActivator {
> private static UdooActivator activator;
> private BundleContext context;
>
> static UdooActivator bundleActivator() {
> return requireNonNull(activator, "activator not set");
> }
>
> @Override
> public void start(BundleContext context) throws Exception {
> this.context = context;
> activator = this;
> new Thread(() -> Application.launch(Udoo15App.class), "JavaFX Desktop launcher").start();
> }
>
> @Override
> public void stop(BundleContext context) throws Exception {
> Platform.exit();
> }
>
> public BundleContext getBundleContext() {
> return context;
> }
> }
>
> Op 20-02-16 om 01:28 schreef Stephen Winnall:
> Anirvan, Kevin
>
> Thanks for this.
>
> I’m an expert neither in JavaFX nor in OSGi, but I think the basis of the JavaFX/OSGi incompatibility is control. To work with OSGi, JavaFX has to relinquish control of its startup sequence to OSGi in such a way that javafx.application.Application (or its proxy) is instantiated by OSGi and submits to OSGi’s bundle/service lifecycle. AN OSGi expert can probably formulate this better…
>
> Platform.startup(runnable) /might/ do it. Platform.launch(class) doesn’t because the object thereby instantiated is always under the control of JavaFX - and thus not of OSGi.
>
> I’m not comfortable using JFXPanel: if I wanted to use Swing I wouldn’t be trying to use JavaFX. But thank you for the hint.
>
> Steve
>
> On 19 Feb 2016, at 16:41, Kevin Rushforth<kevin.rushforth at oracle.com <mailto:kevin.rushforth at oracle.com>> wrote:
>
> And for JDK 9 there is now:
>
> Platform.startup(Runnable);
>
> -- Kevin
>
>
> Anirvan Sarkar wrote:
> Hi Stephen,
>
> FYI, there is another way of initializing JavaFX runtime. Just use:
>
> new JFXPanel();
>
> It is documented[1] that FX runtime is initialized when the first JFXPanel
> instance is constructed.
>
> Also JavaFX 9 will provide an official API to start the FX platform [2] [3].
>
>
> [1]
> https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable <https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable> <https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable <https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable>>-
> [2]https://bugs.openjdk.java.net/browse/JDK-8090585 <https://bugs.openjdk.java.net/browse/JDK-8090585> <https://bugs.openjdk.java.net/browse/JDK-8090585 <https://bugs.openjdk.java.net/browse/JDK-8090585>>
> [3]
> http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable <http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable> <http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable <http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable>>-
>
>
> On 18 February 2016 at 20:08, Stephen Winnall<steve at winnall.ch <mailto:steve at winnall.ch>> <mailto:steve at winnall.ch <mailto:steve at winnall.ch>> wrote:
>
>
> As I understand it, there are two ways of activating JavaFX:
>
> 1) sub-class javafx.application.Application or
> 2) call javafx.application.Application.launch()
>
>
>
>
>
> Op 20-02-16 om 01:28 schreef Stephen Winnall:
> Anirvan, Kevin
>
> Thanks for this.
>
> I’m an expert neither in JavaFX nor in OSGi, but I think the basis of the JavaFX/OSGi incompatibility is control. To work with OSGi, JavaFX has to relinquish control of its startup sequence to OSGi in such a way that javafx.application.Application (or its proxy) is instantiated by OSGi and submits to OSGi’s bundle/service lifecycle. AN OSGi expert can probably formulate this better…
>
> Platform.startup(runnable) /might/ do it. Platform.launch(class) doesn’t because the object thereby instantiated is always under the control of JavaFX - and thus not of OSGi.
>
> I’m not comfortable using JFXPanel: if I wanted to use Swing I wouldn’t be trying to use JavaFX. But thank you for the hint.
>
> Steve
>
> On 19 Feb 2016, at 16:41, Kevin Rushforth <kevin.rushforth at oracle.com <mailto:kevin.rushforth at oracle.com>> wrote:
>
> And for JDK 9 there is now:
>
> Platform.startup(Runnable);
>
> -- Kevin
>
>
> Anirvan Sarkar wrote:
> Hi Stephen,
>
> FYI, there is another way of initializing JavaFX runtime. Just use:
>
> new JFXPanel();
>
> It is documented[1] that FX runtime is initialized when the first JFXPanel
> instance is constructed.
>
> Also JavaFX 9 will provide an official API to start the FX platform [2] [3].
>
>
> [1]
> https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable <https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable> <https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable <https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable>>-
> [2] https://bugs.openjdk.java.net/browse/JDK-8090585 <https://bugs.openjdk.java.net/browse/JDK-8090585> <https://bugs.openjdk.java.net/browse/JDK-8090585 <https://bugs.openjdk.java.net/browse/JDK-8090585>>
> [3]
> http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable <http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable> <http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable <http://download.java.net/jdk9/jfxdocs/javafx/application/Platform.html#startup-java.lang.Runnable>>-
>
>
> On 18 February 2016 at 20:08, Stephen Winnall <steve at winnall.ch <mailto:steve at winnall.ch>> <mailto:steve at winnall.ch <mailto:steve at winnall.ch>> wrote:
>
>
> As I understand it, there are two ways of activating JavaFX:
>
> 1) sub-class javafx.application.Application or
> 2) call javafx.application.Application.launch()
>
>
>
>
>
>
More information about the openjfx-dev
mailing list