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.e...@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 <i...@cuhka.com 
> <mailto:i...@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 <i...@cuhka.com <mailto:i...@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.rushfo...@oracle.com 
> <mailto:kevin.rushfo...@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<st...@winnall.ch 
> <mailto:st...@winnall.ch>>  <mailto:st...@winnall.ch 
> <mailto:st...@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.rushfo...@oracle.com 
> <mailto:kevin.rushfo...@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 <st...@winnall.ch 
> <mailto:st...@winnall.ch>> <mailto:st...@winnall.ch 
> <mailto:st...@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()
> 
>      
> 
>    
> 
> 

Reply via email to