RoboVM is no more, what now?

For the better part of 2 years, RoboVM has been my life. Today, RoboVM announced its discontinuation, abruptly ending that chapter. The amount of things I learned during that short period has easily overshadowed anything I learned during previous jobs, both on the technical and non-technical side. I’ll deeply miss this daily experience.

So, what does this mean for libGDX? There’s good and bad news. Let’s get the bad news out of the way.

RoboVM is dead, what now?

Quite a few libGDX folks have free RoboVM license keys to deploy their libGDX app on iOS. These license keys will continue to work until the 17th of April 2017. However, there will be no further updates to RoboVM, be it new features or bug fixes. The same is true for all the RoboPods the community came to rely on. Moreover, new sign-ups for free RoboVM Indie licenses will also no longer be fulfilled.

In short, if you have a game using RoboVM already, you can continue using RoboVM until the license expiration date. If you start a new game, RoboVM is not an option. In either case, you should move to an alternative as soon as possible.

What are the alternatives?

There are many alternatives to RoboVM, however, none comes quite close to what RoboVM offered. Let’s examine all the available options. We’ll look at them from various viewpoints: tooling support (IDEs, Maven, Gradle), bindings support, binary size, performance and Bitcode compatibility.

Before we dive in, let me elaborate on the Bitcode compatibility, as it is probably the most important feature. Apple recently introduced a requirement that prohibits submission of apps in raw machine code form for watchOS and tvOS. Instead, Apple wants you to submit your apps as Bitcode. Bitcode is a (not quite) machine independent intermediate language from which Apple generates actual machine code on app submission. Any solution that has no clear path to Bitcode is hence at a big disadvantage.

Mobile OpenJDK 9

Oracle recently announced OpenJDK 9 availability for both iOS and Android. While this seems like the most sensible option, it has a metric ton of down-sides as of this writing.

  • Tooling: No integration with IDEs, Maven or Gradle
  • Bindings: No bindings for Objective-C/Swift APIs. No easy consumption of Objective-C/Swift APIs, everything goes through JNI
  • Binary size: The generated binaries include all of OpenJDK, both native code and the class libraries. Apps are huge
  • Performance: It uses Zero VM on iOS, which is essentially an interpreter. Say goodbye to performance
  • Bitcode: Uncertainty about Bitcode compatibility, the interpreter relies on some assembler and signals, both of which don’t work in Bitcode land

None of this is likely to change in the short- to midterm future, so OpenJDK 9 is out.

CodenameOne

No. Next.

J2ObjC

A while ago, Google open-sourced J2Objc. It falls under the category of “transpiler” meaning it translates one high-level source (Java) to another one (Objective-C). Google is successfully using it for a few of their apps, like Google Inbox. Conceptually, it’s very close to GWT, which we employ to get your libGDX games running on the web.

  • Tooling: Essentially a command line tool. There exists a Gradle plugin that takes away some of the pain, but no other tooling is provided
  • Bindings: J2ObjC is mean to allow you to share business logic while you write your UI in ObjC/Swift. As such, there are no bindings. Also notable is the lack of support for most of the Java SE APIs. This makes including 3rd party Java libraries a no-go.
  • Binary size: very good, mostly due to the fact that it doesn’t have to ship a proper managed environment or Java SE APIs.
  • Performance: very good, it’s essentially Objective-C
  • Bitcode: Out-of-the-box, as things are compiled to Objective-C

With a lack of support for Java SE level APIs, the use of reference counting instead of GC, and the fact it only works for Java source code, J2ObjC is not fit for use with libGDX. One GWT based backend is enough 🙂

Avian

Avian is a great piece of OSS tech. JMonkeyEngine chose Avian as their driver on iOS a while ago, so there is some precedent. Avian let’s you chose whether you want to use the Android class library or OpenJDK’s class library, definitely a plus. However, Avian suffers from a few minor and one major shortcomingy.

  • Tooling: No integration with IDEs, Maven or Gradle, save for the integration JMonkeyEngine did with NetBeans
  • Bindings: No bindings for platform APIs, no easy consumption of Platform APIs, JNI hell it is
  • Binary size: Not terrible when using Proguard
  • Performance: The AOT mode essentially takes the JIT mode output and bakes it into an executable. The JIT is rather primitive, and performance isn’t where it should be
  • Bitcode: No path forward to be compatible with Bitcode, as the AOT directly generates machine code. This is the big one

Avian has always been a favorite of mine, as the engineering behind it is top notch. However, using it in production is just a major pita, and the missing path to Bitcode rules it out completely.

Xamarin + IKVM

Back in the olden days, Michael Bayne of PlayN fame took it upon himself to create a somewhat functional path for Java bytecode to live on iOS. The solution consisted of compiling Java bytecode to .NET CIL via IKVM and shipping a heavily cut down version of the OpenJDK class library. I added support for JNI so we could also use it with libGDX. Suffice it to say, it was a Frankensteinian monster of epic proportions. But it worked. Until Xamarin released a new version, in which case non-trivial bug fixes had to be made. Let’s give this a fair shake:

  • Tooling: No integration with IDEs, Maven or Gradle. Integrates with Xamarin Studio and Visual Studio though, including debugging. Otherwise it’s a bunch of shell scripts.
  • Bindings: Excellent, you are able to call into pretty much all native APIs through the IKVM C#/Java bridge
  • Binary size: Good, were it not for the fact that you also need to ship a huge Java class library next to the Xamarin runtime.
  • Performance: Pretty good, although IKVM introduces some suboptimal paths, which makes this solution slower than RoboVM
  • Bitcode: clear path forward, as Xamarin is based on LLVM

Note that the IKVM fork Michael and I worked on is mostly defunct. The cut down class library is also a huge problem, with things like java.net completely missing. Were it not for the last alternative in this list, this solution would probably win.

Intel Multi-OS Engine

Formerly known as Migeran, Multi-OS Engine is a pretty nice piece of tech that let’s you run Java bytecode on iOS. Under the hood, Multi-OS Engine is powered by ART, Android’s virtual machine, which has an AOT compilation mode Multi-OS Engine exploits.

  • Tooling: Integrates with Android Studio, IntelliJ IDEA and Gradle. Used to have support for Eclipse, but it seems that’s no longer available. Also let’s you build and deploy from a Windows machine (using a Mac as the build slave).
  • Bindings: Provides a custom bridge called Nat/J, which is quite similar to RoboVM’s Bro, albeit quite a bit more cumbersome. It appears that all native APIs are accessible from Java via Nat/J, and 3rd party libraries can be bound (semi-)automatically.
  • Binary size: OK but not great. Bigger than comparable RoboVM binaries.
  • Performance: Good, faster than RoboVM in some workloads, slower in others.
  • Bitcode: Currently unsupported, but apparently Intel is working on it.

Multi-OS Engine comes closest to RoboVM along all these axes.

What is the future of libGDX on iOS?

Tomski has already written a new libGDX backend for Multi-OS engine. Here’s the roadmap for libGDX:

  1. Clean-up the Multi-OS backend, integrate it with the libGDX Setup UI, and update the documentation. We are at a 95% status with this, i hope to have the code drop sometime this weekend
  2. Release a new libGDX version next week, that will make Multi-OS engine the default iOS backend for newly created libGDX projects
  3. Begin creating bindings for popular 3rd party iOS libraries. This is where we hope the community can jump in
  4. Keep the RoboVM backend around until the licenses expire (April 17 2017). We’ll try our best to fix any bugs in the backend, however we won’t be able to fix bugs in RoboVM itself

The roadmap of your existing apps should look something like this:

  1. Keep publishing updates using RoboVM 1.14.0 and the corresponding backend
  2. Immediately start adding a Multi-OS engine based version of your app for iOS
  3. Test it and report bugs on our issue tracker
  4. Switch over to Multi-OS Engine as soon as possible

In Closing

There will be some rough edges with the new Multi-OS Engine backend. We are in contact with Intel, who have been very reactive in fixing issues we identified while creating the new iOS backend. Please help test the new backend and report issues, so Intel is able to fix problems on their end.

Multi-OS Engine is free to use, but not OSS. Before you guys start screaming for my head again, I’d like you to read the above analysis carefully one more time. None of the OSS options are even close to production ready. I will however happily merge any and all backend based on those OSS options.

I’d be grateful if everyone funnels their emotional energy created by this announcement into helping out with the new backend, e.g. testing, bindings, reporting bugs etc. I believe this is a much better use of everyone’s time. If you feel the need to vent, I understand. But please don’t expect me to vent with you. The winding down of RoboVM is already emotionally taxing enough for me. My goal is it to keep things running smoothly for everyone, I have no intention to waste time on a screaming contest.

Happy coding,
Mario

154 thoughts on “RoboVM is no more, what now?

  1. I was not aware of such platform. Where does it sit in terms of performance, binary size and bitcode compared to the others? Since most people here are interested in games development, i’m curious to see if there’s a showcase of a game built on Neomades that runs smoothly accross iphones and android devices. Thanks

  2. The spreadsheet was produced by a member of our community trying to improve the performance of Codename One. It shows that Codename One is slower in microbenchmarks and initially showed a much greater disparity.

    There is some inherent microbenchmark penalty in Codename One due to the concurrent GC where we pay a cost upfront and remove stalls as a result. However, the difference is due to many missing basic optimizations e.g. we use the standard malloc/free which are really slow.

  3. Shai, looking at Codename One model of being a SaaS is what was scaring me when I first tried your product. I really didn’t understand why do I need to ship my code to the server to be compiled and I always felt that you just using OSS as branding strategy. It’s like , hey it’s OSS (if you can … good luck trying !)

    Having the software in your hand is a MUST and relaying on a SaaS is pretty danger that many people will try to avoid. We can see that RoboVM users will still be able to compile there code for another year, if it was a SaaS model , I guess not.

    I did play before with Codename One and beside the my dislike of the SaaS model, I always felt that my HTML5 was more real and native than what was produced by Codename One ! (that was few years ago).

    For LibGDX, the items for choosing the next iOS vm are very clear, and the first one is performance. So How about you show us some clear benchmark between Codename one, RoboVM and native iOS code !

    I think Codename One methodology of using source code generation is much better and almost undefeatable by Apple, and this is a big plus.

  4. That’s totally fair criticism. We changed out mind on the open source policy and now do encourage people to work with the code more. The SaaS approach makes more sense especially if you don’t have a Mac or a Windows Machine e.g. we will introduce support for UWP which requires windows but you would be able to build it from a Mac or Linux machine. The inverse is also true for iOS.

    Our UI suffered from lack of refinement over the years so that too is fair criticism. We’ve worked on improving it quite a bit but I can’t say we are at the level of a tool like Ionic out of the door, however this is mostly an issue with the “default look” and not something inherent in the framework.

  5. Google has not been winning. It lost the API copyright case, and now Oracle is ramping up to demands for silly money payouts. God knows why, Androids the best thing that ever happened to Java, but Oracle are bastards who care for nobody but themselves. And it will kill Java one day.

  6. Hi Mario, sorry to hear about RoboVM. In your posts you always spoke very fondly of it and your work there, so I can only imagine it must really suck for you. I hope you’ll find something new that makes you as happy.

    Thanks for your continued work on LibGDX. Take care.

  7. That’s somewhat doubtful given the need of the author to spam this forum. This is a manual translation tool, these are a dime a dozen. The other tools mentioned contain useful things like garbage collection etc.

  8. looking at this topic again I do see the best bet is J2ObjC as I can see that the basic building blocks of Java is there (exceptions, inner and anonymous classes, generic types, threads and reflection) and it’s a transpiler, this gives it a huge advantage that Apple well never be able to break it or kill it without ditching ObjectiveC, but also a disadvantage that it relays on source code …. wait , why should it ?! we have many OSS Java decompilers …. and focus with me here. We can allow any 3rd party libs by on the fly decompile them … so jar–>decompile–>Java source–>J2ObjC–>ObjectC. I think we can also support the missing SE API (correct me plz)

    It seems a bit complex but it’s safer than any other solution and easy to maintain, even if Google stopped supporting the project , it’s much easier to support transpiler than RoboVM works on LLVM.

    This is also will allow all JVM languages to work with libgdx.

  9. One more thing, for any OSS lib we can upload them maven repo to be cached after we compiled them to ObjectiveC, for instance if you are using Google Guava, the system will first check if someone else compiled it and it’s available in public maven , if not it will download the jar and decompile it to source and then do J2ObjC and publish it into maven for others.

  10. I thought it was bad news but after reading this I think it might be a blessing in disguise helping libGdx get less dependent on a single piece of closed-source sw!!

  11. Few questions:

    1. Why the immediate No on CodenameOne? What’s so bad about it?
    2. Xamarin – are you saying that it’s possible to use java code and or packages with Xamarin?
    Is it possible to use native iOS libs as well and bind to them? Is it possible to use a native Xcode storyboard?
    3. Multi-OS – Is it possible to use native iOS libs as well and bind to them?
    This tool seems a bit immature to me, or am I wrong?

    Alex.

  12. Hi, I’m the PMM for Intel’s XDK & MOE. I saw some questions on this forum and (hopefully) thought I’d clear some things up. Intel is actively working on the Multi-OS Engine (MOE) technology. To date we have efforts underway to integrate MOE and LibGDX build and test tool chains. We are also enhancing MOE’s Android Studio plugin and Gradle build script to support LibGDX. And we are working on a LibGDX project template for MOE/Android Studio for one click project setup. The most recent build of Intel’s Multi-OS Engine technology can be downloaded at https://software.intel.com/en-us/multi-os-engine. It is a free product so feel free to look into its capabilities for your project. Please visit our forum to post your questions directly to the engineers for MOE. https://software.intel.com/en-us/forums/multi-os-engine

  13. Hi Terry,
    what code license do you use and how is your licensing structured with Oracle?
    AFAIK the code is based on Android code which is now migrating to the OpenJDK/GPL+CPE source/license so how will you guys handle this?
    And are there any plans to exit the current technology preview status?

  14. Could you clarify that for Codename One too? What Java class library version is Codename One based on? Is it based on OpenJDK? Is it a clean room implementation, and if so, isn’t that the case for Android’s Harmony-based runtime as well? Do you know if Codename One’s GPL+CE holds up against Apple’s TOS? Any plans to switch Codename One to OpenJDK’s class lib now that Google solves the problem of properly implementing it on mobile? That’s one of the biggest reason why Codename One isn’t viable for libGDX atm, with things like java.net not being available in Codename One. For anyone interested, see the Codename One Javadocs on what is and isn’t supported https://www.codenameone.com/javadoc/index.html

  15. Had a quick looksy at your OSS repo. Everything is licensed under GPL, except the class library. That’s Apache weirdly enough. Without a NOTICE file, so the origin and copyright owner of that code is unclear, and i think that’s against the terms of Apache. It also seems like none of the implementations conform to any Java SE or ME profile. Could you clear that up?

    Furthermore, parts of the code that is being shipped in your OSS users apps is licensed under GPL (without classpath exception), e.g. https://github.com/codenameone/CodenameOne/blob/master/vm/ByteCodeTranslator/src/cn1_globals.m. At least that’s my assumption, as the code in that directory has no license headers, so the license declared in the root directory applies (GPL, again without classpath exception). This is a no go on iOS as you know, GPL is against Apple’s TOS (and vice versa). See the VLC case.

    As it stands, Codename One in it’s OSS form is not usable due to it’s inclusion of GPL code in its users apps. I assume you grant a special license to your paying customers?

  16. The code you linked at is the VM itself, since we own that code and wrote it from scratch its GPL+CPE just like the rest of the code. Most of the code is derived from stuff we did at Sun Microsystems and was released as part of the GPL+CPE license of that time. The rest just has a different copyright header.

    If there are mistakes in the license headers/files these should be pretty easy to rectify as we can easily attribute every file. Some files are Apache licensed usually their origin is also from other Sun Microsystems derived projects.

    GPL+CPE shouldn’t pose a problem neither with Oracle nor with Apple licensing. We tried to avoid both Android and OpenJDK code and used neither for most of our code. Some files were taken from Harmony but there aren’t many and they are pretty easy to spot and purge if the need arises. We didn’t use anything from OpenJDK.

  17. What you define as “the rest that just has different copyright headers” is you class library. You license it under Apache not GPL+CE. This means your entire class library was implemented from scratch and not derrived from anything at Sun, they never put any of the class library code out under Apache, and i’m very sure you didn’t get a special license.

    So, with your class library being a clean room implementation, and being licensed under Apache, and not aligning with any Java SE and ME profile, and even if you purged the “few Harmony derrived” files, how is this any different to Harmony/MOE/Android? The legal battle is not over the implementation originating from Harmony.

    Also, if you derrived parts from Harmony, you have to specify it in a NOTICE file.

    All of your licensing is very sloppy, which stands in stark contrast to your claims of being a licensing expert and being careful. You clearly aren’t.

  18. I also had a look at your GC and exception handling. You GC is completely oblivous to the the fact that references may reside in registers. Something you have no power over with your C translation strategy, unless you disable load-stores optimizations, or make all access to locals volatile. This explains the performance deficits of your solution.

    Your exception handling relies on features that are not compatible with Apple’s bitcode requirement. As such, your solution is definitely not the future proof thing you make it out to be. I’m looking forward to how you solve this issue given your translation strategy.

    I feel like i’ve given your solution a fair shake now. I’m happy to put my findings into the blog post above, which still receives a lot of traffic. I could even dedicate an entirely separate blog post just to Codename One. A proper deep dive into your code and sloppy licensing would surely bring up more interesting facts. Any SEO is good SEO, right?

    Or we just leave it be, and tend to our respective communities.

  19. When I talk about my licensing experience I talk about the IP mindset at Sun/Oracle which is somewhat different from what you are discussing. I do know that stuff rather well and have spent a lot of time with IP lawyers, I can’t say I’m an expert as frankly these discussions usually bore me to death.

    A few files within the project were taken from other projects under the Apache license e.g. the tar/gz capabilities etc. use licenses that aren’t the GPL+CPE but aren’t incompatible.

    Every file is trackable thru version control and we reviewed every commit personally, some things might have slipped thru the cracks but should be easily fixable. Relatively to a startup I think we did a relatively clean job with the code “cleanliness” in terms of IP, our main concern was staying away from disputable IP and keeping most things separate.

    If you think we got somethings wrong feel free to file an issue/pull request or just let me know specifically. The notice file isn’t mandated by the license as far as I know but feel free to correct me if I got it wrong.

    We could add such a file but it would just serve to confuse most developers as the major bulk of the code is not Apache licensed.

    In regards to the difference vs. Android this is a big deal. One of the biggest problems Sun always had with Google was their choice of Apache license for the work. This was key to the dispute even back before the Oracle purchase.

    However, since the lawsuit is in place and code could be liable if Oracle wins it might be forced to sue derived implementations to show impartiality otherwise Google could claim that the “law” is only enforced on it hence its “unequal”. I don’t recall the exact legal terms as my brain tends to melt when talking with the IP lawyers.

    To be fair, everyone is at risk of a lawsuit and we mostly vary in scale. We could get sued over some odd patent or something else at some point and since we didn’t derive from OpenJDK we aren’t covered by the patent protection… (which MOE isn’t covered by either although I’m assuming Intel/Oracle have a licensing deal in place?).

    We use very specific language when describing our VM. Notice we try not to say it’s a JVM and use our own branding. When we use the word Java we apply it to Java developers being able to leverage their skills and never in terms to describe our VM.

    Since we are not derived from Android the path for licensing compliance is open to us and we talked about aligning ourselves thru a TCK with Oracle execs a couple of times in the past. This is something I’d really like to do and it would remove the risks once and for all. Currently we are not at that “point” financially. This also means we are probably safe from legal action due to size, once we grow to a point where we attract interest we can easily align. Unlike Android which is HUGE and would probably be hard to align to something like compact1 we can actually reach that within a relatively short amount of time.

  20. Again, your entire runtime class library is under Apache 2. The git repo has no real history on them. Apache 2 requires a NOTICE files, see http://www.apache.org/dev/apply-license.html#new. Claiming it “confuses” your users is a strange excuse.

    You accuse others of licensing problems, whereas you yourself are extremely sloppy with your licensing. Being a startup is no excuse. Don’t you see the cognitive disonance there?

    But i’m glad you finally openly state that you are in the same position as everyone else really, and mostly rely on being a small fish. That’s fair and honest. I just wished one wouldn’t have to wrangle that out of you all the time…

    Looking forward to your reply on the technical merits of Codename One now that the legal aspects have been discussed.

  21. A reference is always pushed to the stack so a live reference should never reside in a register while the sweep process is running on a specific thread. Part of the cost is the over use of the stack, we are optimizing some of that cost away and that was responsible for a lot of the performance improvements.

    We compile to bitcode fine, currently it’s not turned on by default so something might not work there. Can you provide a reference to what doesn’t work there? We use standard C setjmp semantics which are pretty common.

    Sorry I thought we had an understanding, if you don’t want me to answer I won’t answer further. I didn’t mean to be offensive, I was honestly curious what the guy from Intel had to say.

  22. I didn’t say we are on the same boat as everyone else at all. I said we are slightly higher. Where does it say Apache license in our code for the class library? Maybe its a mistake from the github migration.

  23. LOL that’s the retroweaver fork for J2ME compatibility. It’s a fork of an old self contained project that has nothing to do with our runtime 😉

  24. The C compiler can reorder things freely, especially your load stores, unless you make the load/stores volatile. Submit a bitcode app to see where your solution falls apart.

  25. I specifically said there are a few files within the libraries from harmony. Some whole packages in the core and a few files in the JavaAPI. Most of the 180+ files are isolated derived works (e.g. retroweaver, tar/gz etc.). I still fail to see the licensing problems you imply but I thought you wanted to end the discussion?

  26. For me personally, if bugVM is OK with 2d rendering then its enough for me! Hopefully its easy enough to give it a go.

    In the above list I don’t see https://rogerkeays.com/how-to-build-an-ios-toolchain-for-linux-debian-7 as a consideration. There are also other instructions listed about the place. So apple seems to have introduced open source libraries into their build chain which allows non-macosx to build on a jail broken phone. This would be my ideal, plug an old jail broken iphone into a linux box and press go. I am guessing the gcj and other components aren’t up to it and would require even more work than bugvm.

  27. Terry thanks for the input, however, I think lots of people here are worry like me of the future of MOE, whats the road map for the technology and future release license etc.

    Any inputs to relieved the concerns of the groups including me. We want to understand the level of Intel commitment to MOE.

  28. How difficult it is to have a designer to polish styles? Is this a huge effort? I mean visual appeal is very important to sell something.

  29. Wow, the worst-case scenario has happened! I hope you are doing fine Mario. I know you put a lot of time & effort into RoboVM (together with libGDX) and it’s a shame to let it all go.

    In any case, although I think there are legal/policy issues but (I don’t think the big bosses would like that): is there a way to obtain the complete sources for the latest version of RoboVM and put it into github? That way it could continue back as open source?

  30. it should, as the decompiler can output the Java version of Scala JVM bytecode. It should !

  31. I really want to thank Mario for not turning to the dark side and for keeping libgdx alive. Has anyone news on this topic. Is the Multi-OS integrated version out right now?

  32. I wish I knew that. I’m finishing a game right now and it’s sad that I cannot apply to robovm license. Is that any option right now to port my game to IOs. The game is almost finished on Android….

Leave a Reply

Your email address will not be published.