j2objc – Translate Java source to ObjectiveC
What follows is a short dissection. Note that i did not try it out, but only read through the docs as well as the sourcce. If something is inaccurate, i apologize in advance.
j2objc is a Google OSS project that takes Java source code and translates it to ObjectiveC code. This is very similar to what GWT does. Let’s look at some features we’d require it to run say libgdx on iOS.
According to the Google code site, j2objc supports
- exceptions (through ObjC @try/@catch/@finally)
- inner/anonymous classes
Those features are actually quite a bit harder to pull of when translating from Java source instead of bytecode. Chapeau
My only concern is that there is no documentation of what limitations there are for these features. Without having looked to closely, reflection seems to be much more complete than in GWT (where it is basically non-existant). See the Class implementation for example.
I couldn’t find any tests directly covering language features, but i assume that the runtime library test suite(s) are meant to cover those implicitely.
To summarize: lots of crucial language features are there, it is however unclear to what extend they are implemented. Some exploratory experimentation can answer that question.
The second part making up any Java (VM) implementation is the class or runtime library. Here, j2objc only includes the absolute minimum. Whatever is/was needed, was added, anything else was left out. j2objc’s runtime library is a mixture of custom ObjectiveC, Android and Harmony implementations of various core JRE classes.
The core classes (java.lang and some java.utils classes) can be found here. Some core classes and interfaces are written in pure ObjectiveC, e.g. java.lang.Class. Others are written in Java, lifted from Android or written from scratch, e.g. here.
Besides the core classes, there’s also quite a few modified classes from Harmony included, see here. Some of these implement the rest of the java.lang classes , others implement java.io and similar packages.
That looks quite interesting, lots of bases are covered here, given that the Harmony code actually works. The project also includes many tests from the original Harmony project, so one might assume that the runtime library is covered fairly well (see here for example).
Note that there is no abstraction over any GUI toolkit nor is there an implementation of the java.net package. I like that the former, the latter can be easily fixed.
In summary: looks like most bases are covered, there are also tests for almost all runtime library classes. No UI stuff that gets in the way. Neat.
I haven’t looked into ARC yet, but i know a bit about reference counting. For many situations it is sufficient, but as soon as you enter cyclic reference land, you get into trouble. With j2objc you might have to find memory leaks manually, not exactly a prospect i’d look forward to.
What’s interesting is that the j2objc team decided not to use libgc due to Apple recommending against it. I think this makes sense to some degree, altough i’d prefer having a real GC over reference counting. Mono used Boehm on iOS previously (and i think you can still use it if sGen misbehaves), and it doesn’t seem to be to bad. Unity uses Mono, and hence Boehm or sGen as well, and nobody seems to complain. Only a test can really give insight into that issue i guess.
I’m also unclear about how this interacts with threading and exceptions.
In summary: no real GC, “only” reference counting. Might be good enough.
j2objc does not implement JNI, but instead provides something similar to GWT’s JSNI. You can find the docs here. It works by adding ObjectiveC code to your Java source code, which gets woven into the output of j2objc. That has quite a few advantages (JNI is clunky), but also disadvantages (lots of JNI code that can’t be used and has to be rewritten in ObjectiveC).
Implementing JNI is a burden, and for a project of this scope, it made sense to use JSNI. However, the docs are rather sparse, and it’s unclear how to deal with memory managment, threading and exceptions when using native code like that, a problem GWT does not have (except for exceptions).
In summary: good decision to use JSNI-like mechanism, bad for anyone with a lot of JNI code that needs porting, like us
I have three problems with j2objc:
- I don’t like Java source translation. While it gives you way nicer code that’s more easily debuggable, it also limits your JVM language choice to Java. If you use GWT as well, that makes sense of course. It’s not a big deal for libgdx, just a personal preference really.
- Not having a GC is an issue. The whole point of using a managed language like Java or C# is not having to worry about the nitty gritty details of memory managment. You should of course care about overall memory managment to keep the pressure on the GC down. But j2objc might lead to excessive leak detection runs, and i don’t want to waste my time on that. It could be me doing something stupid, e.g. having cyclic references, or it could be a translation error in j2objc.
All these points don’t mean that i think j2objc is a bad project. I actually think it’s rather interesting, and i’d probably use it over XMLVM if my use case was different. Implementing the UI in pure ObjectiveC for iOS makes a lot more sense to me than trying to write a wrapper library like XMLVM does. For games or libgdx, that UI specific code would be very very small, so i don’t consider it to be a burden.
As it stands, it would be quite a bit of work and code duplication to get libgdx going with it. It would be totally feasible though (minus the missing GC which makes me uneasy).
So, if anyone wants to give it a try, let me know and i’ll try to give as much input as i can on how to port the JNI stuff. The Java code should compile pretty much as is, safe for a few threading related classes that might not be supported by j2objc.
I’ll focus my time budget on the MonoTouch backend and on Jack. Even if Jack is a futile attempt, it’s a lot of fun working on it, and i like doing fun things in my spare time.
And that’s that