[I don't usually post very technical material here, and apologies if you're after higher level discussion, but it seemed the most appropriate place for this.]
I was quite thrilled last night to have solved a really frustrating bug in a piece of open source software. First the background, then the problem and finally, for the record, the solution.
I’ve been messing around programming with with JavaFX and would have liked to have used my favourite IDE, Eclipse.
Unfortunately JavaFX has a bit of a poor pedigree. It’s a me-too product being Sun’s response to Adobe Flash and AIR, just as Silverlight is Microsoft’s response. It also doesn’t seem to have been given the heavy backing and attention within Sun that anyone would need going up against the incumbent RIA platform. I see this because (a) the language changed slightly after the first official release (1.0) to the next “minor” version, which smacks of carelessness (or pressures on dates of public announcements); (b) JavaFX application loading seems to be a variable experience, and certainly not as slick as Flash’s; (c) patchy documentation — for your reading pleasure I quote here Chapter 10 of the JavaFX language reference in its entirety:
Chapter 10. Animation
Table of contents
[To do: write chapter]
Added to that, Oracle has just bought Sun. Who knows what the new owners will think of this project… it’s a long way from their core business of providing large scale middleware solutions. It’s a shame, because JavaFX has a lot going for it, and as far as I can tell stands up well technically to Flash; but it needs investment in giving it a lot of polish if it’s to demonstrate this widely. Certainly there doesn’t seem to be a fully-featured IDE readily available.
However, a small team of independent developers wrote an open source Eclipse plugin which was released in December 2008, but the last commit was on 13 January 2009. Since that time JavaFX 1.1 was released in February 2009 which doesn’t play nicely with the Eclipse plugin, but no word from the maintainers on any new releases. It seems to be dormant.
The problem I (and many before me) found is bug 206, documented in bugzilla: when writing seemingly innocuous code the incremental compiler reports
incompatible types found : Integer required: com.sun.javafx.runtime.location.FloatVariable
Which doesn’t read very well but I think means “I found an integer but requred a float”. The error is reported on about one line in five, swamping genuine error messages, and no amount of bracketing, casting or whatever seems to help. It’s clearly frustrated a lot of people and it certainly made me rather disappointed with the whole JavaFX experience.
Anyway, inspired by insights from some of those similarly affected, and after a lot of semi-random hacking and poking I found a solution, which at least works for me.
The solution is to build the plugin yourself from the source, and use that. The original documentation for this is a little terse (well, I struggled a couple of times) so here’s an augmented version:
How to build the plugins from sources
- Install the Eclipse IDE for Java EE Developers from http://www.eclipse.org/downloads/.
- Install the DeltaPack from http://update.eclipse.org/downloads/drops/R-3.4-200806172000/index.php#DeltaPack. (I have no idea what this DeltaPack is, but I think it’s used in this instance as libraries against which the plugin sources are compiled. I unzipped the download and dropped the files into my Eclipse application directory as appropriate: features in the features directory, plugins in the plugins directory.)
- Get the JavaFX SDK from Sun in the form of a zip file. Since it’s currently only available as an executable, you need to download and install that in the usual way (if you haven’t done so already) and then zip it up into a file. I called my file javafx-sdk1.1.zip (though I’ve actually got version 1.1.1 — using only major and minor seems to be the convention).
2. Get the plugin source files
- On the Unix commandline the incantation is
svn co https://kenai.com/svn/eplugin~subversion/trunk eplugin(though I’ve not checked this).
- Alternatively on Windows you can use TortoiseSVN.
- However my Eclipse was set up to use subversion so I imported the source directly into Eclipse:
- Import the files into Eclipse. In Eclipse I did File > New > Project… > SVN > Checkout Projects From SVN. Then use the repository location https://kenai.com/svn/eplugin~subversion/trunk and get the entire contents. I had to accept a few certificates (temporarily) along the way. One time I tried this the new Eclipse project showed lots of Java errors (libraries not found), but they didn’t seem to cause a problem.
3. Amend and then run the build
Running the build that came with the source files didn’t work, and I needed to amend the Ant build.xml file. I had to change the original line
<property name="javafx.sdk.root.dir" value="javafx-sdk1.0"/>
<property name="javafx.sdk.root.dir" value="javafx-sdk1.1"/>
That is, I had to change the javafx.sdk.root.dir variable to match the name of my JavaFX SDK zip file, but without .zip bit.
Now you can run the build from within Eclipse. To do this I did: Right click the build.xml file in the Eclipse package navigator, choose Run As > Ant Build… Go to the Main tab, then the Arguments box and fill in these arguments
-DeclipseDir=<path> -Djavafx.sdk.build.url=<url_to_zip> clean build-windows [build-macosx] [build-linux]
Note that you need one file path and one URL, and you need to name the operating system you’re building for. This took a few minutes to run, but it completed without problems.
If you’re not doing this from inside Eclipse you can use Ant directly.
4. Install the results
The result of this is in a new dist directory. Here you will find a few files, but the one you’re interested in is the .zip file. In my case it was called com.sun.javafx.eclipse.feature-win32-win32-x86-1.0.1.zip. This is an Eclipse plugin. Unzip it and drop the contents into the relevant places in your Eclipse install directory: features in features, plugins in plugins.
I hope you find this goes relatively smoothly.
Why did this happen?
Honestly, you think I know? My guess is that the plugin was built with JavaFX 1.0.x embedded, and those of us with JavaFX 1.1.x get compatibility errors; recompiling from sources ensures your new plugin in built with your current JavaFX SDK. If so, that’s a pain, as it may mean you’ll need to do all this again when the next JavaFX SDK comes out. But, hey, you’ll get a few hours of happy coding done in the meantime.