Hacker News new | past | comments | ask | show | jobs | submit login
J2ObjC is a command-line tool that translates Java to Objective-C (developers.google.com)
56 points by SerCe 11 days ago | hide | past | favorite | 34 comments

I used to work on Sheets. We built the “engine” of Sheets in Java. Then we used GWT to transpile to JS (probably switched to J2CL by now). We built Android version by compiling the Java code against different libraries. And we were the first (or one of?) teams to launch an iOS app using J2ObjC.

I was amazed that we were able to pull it off, tbh. The biggest issue that I remember was that the Java collection classes didn’t transpile well to JS. So we made an abstraction over them. Java code used the native collection classes, JS code used native JS arrays, etc.

This may be a noob question - how do you go about filling in the other side of that abstraction in the JS (presumably) post transpilation? Is it just that you had a set of files in JS developed separately and the build/deployment system could inject those files in specific expected areas?

Yes, you have it exactly right. We basically had three different hand-coded implementations of the same classes, each in a different language.

While working at now long-gone mobile game company Digital Chocolate, they developed their games using a pretty clever but also very complex process of writing the games in Java, then converting that Java to whatever the target mobile phone platform required.

For iPhone, which they arrived late to the party, the code was compiled with an tool built inhouse that converted the Java code to Objective-C++, with homemade garbage collection code. The end results were impressive from a standpoint of having the ability to target 50+ different devices at the time (when you still had J2ME phones on the market) but the performance was just not there for the iPhone, the games ran pretty poorly on that platform and ultimately I think that is one of the reasons they went bankrupt.

Still, the tech was quite fascinating, very difficult to debug and slow to compile. First you had to run the whole project through the Java -> Objective-C++ converter which took quite some time, and then you had to compile this huge Xcode project, in total I think it could take easily like 30-40 minutes just to get build. Debugging was a pain in the ass also, the code generated was not easy to read or very concise.

Wondering if they maybe used this tool ? When was this project started, any idea ?

It was started by Inbox.

One should probably also mention its sibling project, J2Cl which translates Java to Javascript (with very very good quality might I say!).

With android apps being written in Java, Google (and anyone actually) can share code between the web, android and ios at the same time. I’m no google employee, but from what I’ve read they do use this to share the difficult logic of google drive apps between all platforms, while letting the platform-native frontend do the rest.

> J2Cl which translates Java to Javascript

Oh that's sure an interesting project. A shame it apparently requires the use of Bazel as the build system. I wish I could just add it as a module to my existing Maven project and rewrite my frontend code from TypeScript to Java — but that's Google, and Google can never stop inventing their own ways of building things.

edit: I might try https://github.com/Vertispan/j2clmavenplugin

There are third-party maven and gradle integrations and plugins at various stages. And you can also run bazel -s to log the exact commands it is running (basically j2cl with annotation processing plus closure-compiler). Though extracting good pairings of j2cl, closure-compiler, gwt and jre-emul libs etc tends to become a pointless chore with j2cl, closure-compiler being updated all the time without documented releases other than timestamps. Last I checked, closure-compiler was at a 2020ish rev in a recent j2cl bazel build checkout only slightly newer than the initial 2019 release, with j2cl apparently focussing on kotlin and also an experimental wasm target requiring wasmgc hence Chrome.

It's a pity Google doesn't anymore see value in external input/testing for j2cl and closure-compiler since these are decent projects.

TeaVM converts Java to JS, and it has first-class maven support.


It runs byte code in a JS-(or WASM) implemented JVM, isn’t it?

It is really fast, but slightly different than J2CL.

TeaVM transpiles Java bytecode to native JS, only keeping the required classes. The output is compact, efficient, and fast to download in a browser. No interpreter or runtime is used, which makes TeaVM apps fast and light.

Oh I see. The difference is that it works from class files, not source (making other jvm languages supported as well)

We are mostly targeting enabling GWT applications to be able to (relatively seamlessly) update to J2CL as a compiler, but are definitely interested in apps or libraries starting their lives as a plain Java project and expose it to JS/TS/closure in a variety of ways.

Aside from the github repo, most of the conversation as we work on this happens at https://gitter.im/vertispan/j2cl - feel free to stop by to ask any questions or share a use case that seems under-represented.

I've never used bazel before. Is it that bad?

Doesn't matter whether it's good or bad, I already have an existing Maven project I would like to try this in. Besides, Maven and Gradle are simply what I'm used to when working with Java projects. Yet another build system is about the last thing I need. I consider building Java to be a fully solved problem.

I use it in a few projects, all are polyglot monorepos. I think bazel really shines in that setting. I have one tool to interact with my codebase. I use it to manage all build, test, and deploy, but also code generation, running local dev servers. I think its worth the hassle of setting it up for large multi language projects.

As far as I know it’s not necessarily bad, it’s just not standard, especially not for java projects, so it may require strange file hierarchies.

Bazel doesn't enforce a structure. Bazel makes you add WORKSPACE and BUILD files throughout your project to describe your targets and their dependencies.

I once had to convert a Java program to C++ and once from Swift to Java (or was it the reverse, it's been a while). In each case it could/should have been done manually but I was curious how far I could get by automating it since the code bases came complete with unit tests that I could also convert to give some confidence. The challenge with the C++ one was returning heap allocated objects which I merely returned const references that were copied by the caller and that process could repeat through multiple call/stack frames. I was concerned about the performance of all the copying but it didn't factor in at all. I'd say that 95%+ was automated and worth taking the approach. The Swift one was way more challenging in that I didn't know it and got annoyed by the number of different ways that lambda functions can be written. Swift syntax is special.

J2ObjC does not provide any sort of platform-independent UI toolkit, nor are there any plans to do so in the future. We believe that iOS UI code needs to be written in Objective-C, Objective-C++ or Swift using Apple's iOS SDK (Android UIs using Android's API, web app UIs using GWT, etc.).

Weird statement by the company who created flutter.

This is by design: the project came out of Inbox.

The thinking was that having portable widgets was not a good thing and for the highest quality app you still want native UI, while having portable "model" [ as in model in model view controller ] code.

Flutter was developed by a different team, and has a different philosophy about this - and in part this is driven by solving for a different goal. For super sophisticated complex apps with large teams, native is still the way to go. If you look at all of Google's own major apps, they are all native.

That’s not actually true though I don’t think.

The majority of their revenue by way of ads is handled via AngularDart in the web interface and Flutter on mobile devices.

They literally put billions of dollars of mission critical stuff into Flutter at this point. Same with the entire Google Pay ecosystem and soon to be with Fuschia.

I don’t think Flutter is a great tool for a bunch of use cases but that list is shrinking a lot with each release. It certainly has all the moving parts needed in terms of technical capabilities to investment to make it a default choice for a lot of things in the future.

Different teams with different goals. Shared engine logic + platform native UI is a strong approach to building cross-platform apps. You get to share code and have performant native-feeling UIs.

You still have to staff up your platform teams, though, and now you have the cross-language barrier to deal with in each code base, so each team needs expertise in that as well.

Flutter lets you have just one team write one app, maybe with different themes per platform, but it's still all in the same language and runtime. The cost being that you get not-quite-native UI and performance, but maybe that's an OK trade-off.

J2ObjC is a very old project, long predating flutter, and Google is a big company.

I think react native changed the hybrid landscape and they jumped onboard. As a dev who works with RN a lot I find SwiftUI to be a pleasure. Just a lot of legacy to deal with

There's lots of people working at Google.

Not trying to diminish the achievement, but this is really old and I’d be surprised if it’s still relevant for a significant number of people, seeing that native iOS and macOS development has moved to Swift for quite some time now, and using Java as language for some kind of proto-codebase feels like a niche case.

It's useful if you want to share code across apps. This is particularly useful for business logic and such, not as much for UIs.

The other cross-platform alternatives are C++ (potentially faster but unsafe by default with footguns galore) and JavaScript (incredibly slow - have to RPC everything into a webview).

Rust might also be a good fit for something like this, but I'm not sure what the story is for compiling Rust for Android JNI or with Objective-C/Swift.

And on Android, Kotlin seems to be pushed.

Definitely relevant - iOS ships lucene code that is transpiled to over a billion devices.

Was this at all related to Apportable, which Google acquired?


Nope. Apportable went the other way, compiling Objective-C on Android, and linking against the Android NDK. They did have a tool for automagically converting .jar files into .frameworks (that ultimately just linked against JNI) so you could code against the Android SDK (or 3rd-party Java libraries) in Objective-C as well[0], but J2ObjC translates Java primitives and standard library classes into their corresponding Objective-C equivalents, eg java.lang.String -> NSString (although Apportable did do a few of those as well for better interoperability).

[0] There was this grand idea to make Objective-C the language for mobile development, with an "Apportable NDK" on every platform (but iOS). It wasn't that far-fetched. The NDK was terrible at the time, and Apportable's was faster, less crashy (free couldn't call malloc in low memory situations, for instance). And then Apple released Swift. And then Google came along.

The NDK has improved in the meantime, but it remains quite bad when compared with similar SDKs, including the recently released AGDK.

Better ObjC than C++, as was the case on most mobile platforms previously. Imagine, message passing everywhere.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact