If you follow my blog you’ve noticed that I’m currently investing some of my OSS time into JavaFX. The project I’m working on is named e(fx)clipse and until now I’ve been working most of the time on the tooling front but like I promised I don’t only want to provide tooling but also a runtime framework.
So when it comes to runtimes the most important thing for me is that I’m able to use an OSGi-Container (for me equinox is the one with the highest priority) and because JavaFX is NOT shiped with the appropriate OSGi-Metadata it is not as easy to use JavaFX 2.0 in an OSGi-Application.
So I explored multiple different options:
- Repackage it
- Use a bootclass-path
- Use Adapter Hooks
The important things for me are:
- I don’t want to modify the plain javafx-jar shiped by Oracle – not even sure I would be allowed to do that
- I’d like to have seemless integration into PDE, so developing an JavaFX-OSGi application should be not different to SWT/Swing
- I’d like to use the standard export and build tools (Product-Export from IDE, maven-tycho)
- I’d like to follow OSGi best practices as much possible (e.g. you do a package-import in the client-bundles, let OSGi-wire up stuff at runtime appropriately, …)
In the end I came to the conclusion that using Adapter Hooks is the way to go. So I went ahead and implemented support for this which will make it extremly simple for you to implement JavaFX 2.0 application with Eclipse, Equinox and e(fx)clipse – There are still some glitches in Eclipse to make the PDE-export and JDT happy but I’m going to look into this later on because once you know them they are not really a problem to solve.
I’ll describe in more detail on how to create an (Equinox)OSGi-enabled JavaFX-Application when I release e(fx)clipse 0.0.6 but here are some screenshots to see that this isn’t a pipedream.
Inside Eclipse it looks like standard OSGi-Project:
And here the exported application:
As always when having problems questions about some OSGi stuff Tom Watson from Equinox helped me to get into the right direction.
For those interested in how I managed to teached Equinox the location of the default JavaFX 2.0 classes can look at my github-repo where I already pushed the code and examples to.
Another option, which I used successfully with JavaFX 1.2/1.3, is to embed OSGi into the JavaFX runtime and export the JavaFX API packages into OSGi using “org.osgi.framework.system.packages.extra”.
Hi Neil, how did you embed OSGi in the JavaFX runtime in 1.x? I have to admit have never worked with 1.x but your solution might be interesting. One of the major problems I had with 2.0 e.g. when repackaging was that e.g. the native libs couldn’t be found anymore. So I decided to go the Adaptors way where I specialized the ClassLoader for my wrapper bundle to look up classes using an URLClassLoader, how dirty in OSGi-terms would you consider my current solution, can this solution be applied also to other OSGi-Implementations e.g. Apache Felix?
I did the same thing. I included some slides talking about why in a JavaOne talk last year, albeit using Felix rather than Equinox. Intro track, so forgive the basicness of the explanations,
from about slide 26.
At the time, the license didn’t support bundling the JavaFX libraries. But in any case I doubt you could mix two versions of JavaFX anyway as that would imply trying to insert objects and their peers from one version of JavaFX into a scene graph of another version of JavaFX. So an OSGi bundle of JavaFX itself wasn’t going to offer any advantage. So instead the JNLP that ran the program was configured to fetch the JavaFX libs (as for any other JavaFX jnlp) and a Felix config variable was set to add them to system packages (ie, just treat JavaFX as part of the underlying Java platform, rather than as a bundle). And it all worked very simply, but let us load as many JavaFX or Swing view plugin bundles as we liked in OSGi.
wel treating javafx like you treat java.* packages was something I also throught about but afer discussing with Tom Watson I came to the conclusion that using a phantom package which exports the necessary javafx-packages client bundles can import is the way to go. The solution for the treating javafx can be done quite easily in equinox by using a bootclasspath and or adaptor hooks. I’ve decide to follow OSGi-Rules that all NONE java.* package have to be imported and so the only solution was to use a phantom package. Please note that I’m not bundling the JavaFX libraries but I look them up in the installation directory at runtime.
Hi Tom. As you probably know it’s quite easy to embed OSGi… with the new standard launching API in R4.2 it can be as little as five lines of code. So I would run a “standard” JavaFX runtime (at the time FX had its own command line launcher, I don’t know if 2.0 does this because I’m a Mac user), meaning that JavaFX was effectively on the boot classpath, just like Swing and AWT. Then I just fired up an OSGi framework using the launcher API. This works for any R4.2 compliant framework, including Equinox, Felix and KF. Feel free to ping me for further details if required!
JavaFX 2.0 doesn’t come with a special launcher but when exported as a runnable jar it embeds into the MANIFEST some launch code which looks up the javafx.jar so the javafx stuff never gets part of the bootclasspath and hence I’d have to set this one my own using command options so the solution you used in 1.x is not possible in 2.0
Thanks Tom. Can you explain a little more, it sounds very strange. If JavaFX libraries are never on the classpath then how do FX apps work at all? That is, how does a “normal” (non-OSGi) FX app access the libraries?
Well because the sources are not available one can’t know (without reverse engineering the byte code). JavaFX requires you to subclass an Application-class (you can see mine in ), there are ant tasks to package a runnable jar who add some extra classes to ones jar and sets the as the Main-Class. So the magic of the classpath setup happens in the added classes and my wild guess is that they are creating an URLClassLoader in there, add the javafx-jars they looked up somehow on the system and set it as the current threads ContextClassLoader.
Ouch! In that case, good luck with your solution. It sounded dirty to me, but maybe that’s just what it takes.
It seems the Sun folks simply can’t help themselves; they absolutely have to ram idiotic classloading hacks into every library they touch. Sad.
Well – what I’m saying naturally is guess work without having access to their code – the only one thing i know for sure is that I’m launching a standard jar and somehow those classes manage to put the javafx libraries on my classpath and if this is the case I think my solution with the fake with an empty bundle which looks up the classes not in the bundles-jar but somewhere else is not that bad.
Pingback: Java desktop links of the week, September 26 | Jonathan Giles
Pingback: e(fx)clipse 0.0.6 released | Tomsondev Blog
I tried out your sample on my side the sample doesnt work… No Exception.. The OSGI container starts up without any exception, but the doesnt start the FX – Application.
Do you have any idea??
Let’s start with the simple question. What do you have installed (do you e.g. have e(fx)clipse installed), a plain Eclipse SDK, … and what have you checked out from the git-repo.
I have installed the latest e(fx)clipse from our site and the JavaFX Runtime. I also add the FX-Runtime to the Preferences to use the Java Library and from the git-repo i checkout the OSGI-Sample and imported the plugin into my workspace. After configure my OSGI-Run-configuration the OSGI-Container starts and all Bundles are installed and resolved but the sample bundle doesnt start the FX-Application (i checked with the debugger, i add a breakpoint into the method where the JX-Application is build but the debugger doesnt stop there…)
So you fetched “at.bestsolution.efxclipse.runtime.examples.osgi”? In there you should find an OSGiApp.product-File. It looks like it is not up-to-date (at least when executed in e(fx)clipse 4.2). Go to the Dependencies-Tab and hit “Add Required Plug-ins”, afterwards change to the Overview-Page and hit “Launch an Eclipse Application”
sorry my fault, i started the application as a standard OSGI-Application and i would ask you, if you have some free time, its possible to make a short chat together i have some issue about your implemenation…
I’ve sent a mail to your address. If you didn’t get it just tell me where to send my contact informations to.
I want to create an Eclipse-based application with JavaFx front-end. The front-end should be runnable in web-browser and as standalone-application. I don’t want to create an rcp-application that uses the Eclipse-UI as front-end but I want to use Eclipse as Plugin-Framework so that my application can be enriched by eclipse-plugins.
Is the way your described in your article the way I need to go? Or is my requirement not possible with eclipse and JavaFx now?
Could you provide a link or a description how I have to setup my project?
You should as a first step install e(fx)clipse – if you haven’t done so yet. The git-repo has some example application based upon OSGi and e(fx)clipse runtime integration. If all you want is the OSGi integration and you want to deal with the other things your own that’s all you need. The up coming 0.0.13 release will allow you ship JavaFX with your OSGi application instead of falling back to the system installed one.
Above the OSGi integration e(fx)clipse also provides integration into the Eclipse 4 Application Platform so that you get the modeled UI and DI from there but if you want to run this inside an applet/webstart you’ll have to keep the download size as small as possible and so it might not be an option.
So yes e(fx)clipse provides you with everything you need to write applications who use the eclipse plugin concept (OSGi).
Hi every one,
are there any solutions for Felix?
There’ve been mails on openfx-dev from someone who works with felix but they are rebundleing javafx to run on felix – I planed to look into felix and do something similar the netbeans guys are doing to make Netbeans modules work in an OSGi-Env but didn’t have enough time.