1. Overview
Gluon VM is a set of software components, that combined allow developers to write Java Applications and run them on mobile or embedded devices. Gluon VM contains an AOT (Ahead Of Time) compiler that compiles the Java Bytecode into platform-specific native code. While this is a nice to have on many platforms, on the iOS platform this is a fundamental requirement, as the typical Java Runtime approach (compiling code when it is often used) is not allowed by Apple. Using an AOT compiler transforms your Java application into a native (iOS) application, which follows the same rules as other native apps.
For the end developer, the easiest way to get started is by installing the Gluon plugin in your IDE (NetBeans, IntelliJ or Eclipse). This is explained at http://docs.gluonhq.com/charm/latest/#_getting_started
The Gluon plugin for your IDE will invoke the jfxmobile plugin (which is maintained at https://github.com/javafxports/javafxmobile-plugin).
There are 2 versions of the plugin: the classic 1.x version will use the "old" approach. The 2.x version of the plugin leverages Gluon VM. If you use your IDE to create a new Gluon Mobile project, you can choose between a number of templates. The template called "Single View Project on Gluon VM" creates a project with a build.gradle file that refers to the latest stable jfxmobile 2.x version
At this moment, Gluon VM allows Java 9 applications to be deployed on iOS devices. For Android deployments, the IDE plugins support the JavaFX 9 API’s, and at runtime the application will run using Java 8 API’s
2. Versions
June 13, 2018: jfxmobile 2.0.26: add ClassLoader, print stacktrace when JavaFX App start fails
May 12, 2018: jfxmobile 2.0.21: introduce abstractmethoderrors, load Boolean FALSE/TRUE
jfxmobile 2.0.21: fix exception handling in class initializers and constructors
April 3, 2018: jfxmobile 2.0.19
-
support for MethodReferences to an instance method of an object of a particular type.
-
remove some debug info (https://github.com/javafxports/javafxmobile-plugin/issues/46)
-
allow to retry ios deployment when device is locked (https://github.com/javafxports/javafxmobile-plugin/issues/47)
-
allow duplicate directories (https://github.com/javafxports/javafxmobile-plugin/issues/44)
Mar 21, 2018: jfxmobile 2.0.18 now requires native libs have a JNI_OnLoad_L handler
Mar 20, 2018: jfxmobile 2.0.17 has stackwalk API, allowing ConsoleLogger to be used
Mar 14, 2018: jfxmobile 2.0.16 has jni support for throwing exceptions, fixes bugs
Mar 6, 2018: jfxmobile 2.0.13 allows for createIosApp task, fixes bugs
Feb 23, 2018: jfxmobile 2.0.12 removes debug info from libboson.a and javafx.graphics
Feb 22, 2018: Version 2.0.11 adds support for Reference collection.
3. Known Issues
3.1. Compiling classes takes forever, or stops with StackOverflowExceptions
See https://github.com/javafxports/javafxmobile-plugin/blob/master/README.md, point 4 under iOS
3.2. No iOS simulator found or deploying to simulator failed, but the app was created
When running:
./gradlew launchIPhoneSim
if you get this exception:
java.lang.RuntimeException: No iOS simulator launched, and couldn’t find iPhone
you can try to deploy the app into the iOS simulator directly with Xcode.
Follow these steps:
-
Run:
./gradlew launchIPhoneSim
-
When it fails with the mentioned exception, go to
ProjectApp/build/gvm/
, and verify the app is created.
If you don’t find the project ProjectApp.app
file, then the problem is elsewhere, and the following steps won’t apply.
-
Open Xcode, and in the top left menu, select
Open Developer Tools → Simulator
.
It should open a valid iPhone simulator. If you don’t get one, go to Simulator→Hardware→Devices→Manage devices
and check one from the list:
Or create a new device from the +
button.
-
Once you have an iPhone simulator running, you can drag and drop your app
and it will start installing it:
When the installation finishes, just tap on the app to open it, and you’ll be able to test it.
3.3. Deploying to iPhone/iPad fails but the app was created
When running:
./gradlew launchIOSDevice
if you can’t deploy to your device for any reason, but the app was created, you can try to deploy the app into the iOS device directly with Xcode.
Follow these steps:
-
Run:
./gradlew launchIOSDevice
-
When it fails with the mentioned exception, go to
ProjectApp/build/gvm/
, and verify the app is created.
-
Open Xcode, and in the Window menu, select
Devices and Simulators
.
-
You should see your device connected, and a list of installed applications.
-
Finally you can drag and drop your app and it will start installing it.
-
Open your iPhone/iPad and launch the app.
3.4. Compilation fails when casting JDynamicInvokeExpr to InstanceInvokeExpr
Although compilation of specific classes fails, the Higgs compiler will continue since it is very well possible the affected method is not used in your application. In case it is used, a runtime exception will cause a crash.
The Higgs compilation gives the following stack:
java.lang.ClassCastException: soot.jimple.internal.JDynamicInvokeExpr cannot be cast to soot.jimple.InstanceInvokeExpr
at com.gluonhq.higgs.MethodCompiler.invokeExpr(MethodCompiler.java:695)
at com.gluonhq.higgs.MethodCompiler.assign(MethodCompiler.java:1080)
at com.gluonhq.higgs.MethodCompiler.doCompile(MethodCompiler.java:376)
This is caused by an invokedynamic expression that Higgs doesn’t understand yet.
Typically, this happens when using classes compiled with Java 9 without supplying
-XDstringConcat=inline
. Higgs currently doesn’t support JEP 280.
Solution: compile your code and dependencies with -XDstringConcat=inline