Inspired by a recent thread on e(fx)clipse user forum “Why some things don’t work out-of-the-box when using JavaFX instead of SWT”. I think its time to take a look at the current state of JavaFX 2.2 on OSGi.
The first thing we need to decide is which deployment strategy we want to use.
The 2 possibilities are:
- Make JavaFX 2.2 a prerequisit on the target system which requires your OS-X/Windows users to install OpenJDK7u6. For Windows users there’s another option because they can install the JavaFX-Runtime seperately
- Ship JavaFX 2.2 with your application as an OSGi-Bundle
The prerequisit deployment
A reason to follow this strategy could be for example that you want to keep your download size as small as possible. If you think this is not a problem then think about the following: If you want to ship only one application “binary” you’d have to package JavaFX 2.2 runtime (Java-Sources+Native libs) 6 times (Mac, Win32_x86, Win32_x86_64, Linux_x86, Linux_x86_64)!
Even even if you require your users to have Java7u6 installed which has the JavaFX-runtime co-installed the JavaFX binaries are not on the bootclasspath, nor are they exported by OSGi by default so your application will fail to start.
The only solution I have found and implemented so far is to Adaptor_Hooks in Equinox to dynamically locate the JavaFX-binaries.
As far as I’ve heard JDK8 will have the javafxrt.jar on the bootclasspath and so that I can be supported by OSGi-Implementations the same way they currently support the usage of swing.
Repackage JavaFX for OSGi deployment
Since 2.0 many problems with JavaFX on OSGi have been solved and so straight repackaging the javafxrt.jar as an OSGi-Bundle should work. One can use the Eclipse wizard to repackage the jar and afterwards only has to add the Bundle-NativeCode-Code header and the native code.
Now on first sight this works but there’s one big problem with this. The code in JavaFX which is detecting the native code follows those steps:
- Locate native code relative to javafxrt.jar if that fails
- Locate native in the java.library.path if that fails
The problematic part in the above strategy is the 2nd one.
Let’s suppose with have repackaged JavaFX 2.2 but the user has installed Java7u5 which has JavaFX 2.1 co-bundled your java.library.path looks like this.
C:\Program Files (x86)\Java\jre6\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files (x86)/Java/jre7/bin/client;C:/Program Files (x86)/Java/jre7/bin;....
Your application will not load the native code from your repackaged JavaFX-OSGi-Bundle (step 3.) but the native code inside your Java7u5 install which is the one from 2.1 which means your Java-Code (2.2) and Native-Code (2.1) won’t match.
Repackageing as a “deployment container bundle”
The approach here is that one repackages the javafxrt.jar and the native code as an OSGi-Bundle with a predefined name (e.g. javafx.osgi) but you don’t export any packages from it but see it only as a deployment unit. At runtime you once more use Equinox-Adaptor_Hooks but instead of locating the jar somewhere on the system you resolve your deployment container bundle and extract the DLLs and javafxrt.jar from there. If you used
"Eclipse-BundleShape: dir" you only have to detect the install location because the jar is already exploded.
Although it looks like the default approach to make use of JavaFX in OSGi would work (Straight Repackageing) fails when taking a closer look and this will not change until JavaFX 3.0 (shipped with JDK8).
So currently only the only solution for me as of now is the use Adapter-Hooks which e(fx)clipse uses, promotes and provides tooling for.
Thanks for your work on this, it’s very interesting.
I gave it a quick try and added a JavaFX chart to an eclipse view. So much easier than BIRT. I would be helpful if we could the the OSGi magic pre-packaged – the whole download the zip version is kinda confusing. I’m also interested in how the data binding stuff will work. Does the JavaFX data binding work and play with the Eclipse data binding? I’d love to bind an EMF model to a JavaFX chart.
On the prepackage stuff: yes that would be possible. I guess once 2.2 is shipped we could do such a prepackaging and allow people to install it into their host eclipse.
On the databinding stuff: yes those 2 play together very nice. There is an implementation of Eclipse Databinding available for JavaFX-Properties. If you add a dependency on “at.bestsolution.efxclipse.runtime.databinding” you should be able to create IObservableValue from a FX-Property using JFXBeanProperties.value(“propName”), but the opposite is available as well: If you have an IObservableValue or IObservableList you can adapt them to their FX-Counter-Parts using AdapterFactory.
one question: Did you made any expericences integrating the JavaFX Webview (Webkit Browser Plugin) into an Eclipse RCP ViewPart?
I’m looking for an embedded HTML-5-browser for RCP and this is in my opinion the only way to do that?!
The default browser view only supports a Mozilla without HTML-5.
I know that people embedded WebView into RCP using e(fx)clipse but haven’t done some my own. Isn’t it possible with latest SWT to force it using WebKit as the browser of choice as well? Anyways – I think going with WebView is probably a good idea!