I’ve already blogged about running JavaFX on Android and discovered that my first generation Nexus 7 is quite able to run such an application, including an animated gauge. So it is time to step up the ante and go for a fully working application.
Yes, applets / Swing applications can look pretty decent as well. And I think it hasn’t lost much of its looks in these 10 years, it even has some animation going on. The backend also had a web application for administrative functions, but I now just SQL the stuff straight into the database, I don’t need all the fancy logic that was in the web application.
Recent developments in browsers means that I can only start the applet in IE at the moment, and Oracle will discontinue the plugin completely. So that means I either convert the applet into webstart application, or write a JavaFX version, that just happens to also run on Android and other mobile hardware.
There isn’t much challenge in the first option, is there? So the choice was easy.
Following my own rule to first get all of the technical obstacles out of the way, before starting to make things look pretty or work on trivial stuff, I created a JavaFX application that has a date picker (JFXtras’ CalendarPicker), a table, a tree and some buttons and made them work.
Yeah, that is a pretty boring GUI, but it took quite some steps to get there, because exchanging data with the backend using Hessian on Android was not trivial. First I (naturally) tried the Hessian library that is used both by the Server and the Applet. It works perfectly on a windows desktop, but on Android it fails:
Strangely enough the Hessian jar is included and processed by dex, so there is no obvious reason why the class can’t be found. Luckily José Pereda showed me that more people already ran into this problem.
Following his advice, the next attempt was using Hessdroid. But it is only available as source and is compiled against Android 1.6. Some frustrating tweaking and twiddling later it was compiling against Android 5.1, but unfortunately not working either:
com.caucho.hessian.io.HessianProtocolException: expected hessian reply at 0x48 (H)
In the discussions another Hessian port by Flamingo was mentioned, but that project has completely disappeared from the interwebs. Googling revealed that it was used in a project called “JFXperience“, and that was still around. But more importantly: it had the supporting jars in its source tree! So I downloaded the sources, and found the ‘flamingo-android-hessian-client’ jar in there… But no luck again:
java.lang.NoSuchMethodError: No virtual method putDouble(Ljava/lang/Object;JD)V in class Lsun/misc/Unsafe; or its super classes (declaration of ‘sun.misc.Unsafe’ appears in /system/framework/core-libart.jar)
Sun.misc.Unsafe? Oh oh, that probably won’t be easily fixable.
I was about to give up and settled on the idea that I had to build a REST service, when I noticed a blogpost by Monkeyboy mentioning a stripped down version of Hessian. Hmmmm. Maybe stripping it down… You never know until you try. So I downloaded the sources, the compilation went without a hitch and, well, you’ve seen the results! Thank you, Monkeyboy!
So now all the technical issues are out of the way, I can move forward with finishing up and polishing the JavaFX application. But I figured I should document my travels in case someone else runs into the same problem. And if that source link goes down, I’ve got a copy tucked away in my Nexus.
10 year old software and I can still build on it. Ain’t Java great?
Update 2016-02-20: turns out Hessian has a problem when using a host name instead of a direct IP when connecting to the server, it crashes without any explanation. One would think that using InetAddress.getByName(hostname) to convert the host name to an IP address would solve that, but apparently that is what makes the application crash!