J2ObjC. The good, the bad, and the ugly

J2ObjC. The good, the bad, and the ugly

Vitaliy will show that the war between mobile platforms is over. After several years of active competition, we’ve got two operating systems with almost the same quality and feature set. The closest competitors of Android and iOS are far behind in market share. For mobile developers this means that all further projects should target at least two platforms. In this talk, Vitaliy will go through build configuration, development process and project impact created while using j2objc – Java to Objective-C translation tool developed by Google. J2objc goal is to write an app’s non-UI code (such as application logic and data models) in Java, which is then shared with no editing by Android and iOS apps.


Vitaliy Zasadnyy

August 15, 2016


  1. 1.

    @zasadnyy The good, the bad and the ugly J2ObjC Vitaliy

    Zasadnyy Head of Mobile @ GetSocial
  2. 2.

    In yellow boxes like this one you can find comments

    to the slide. Enjoy the presentation and if you have any questions, feel free to reach me at v@zasadnyy.com
  3. 3.

    @zasadnyy Chronology: - April 2012, GDG Lviv was born -

    September 2012, Google announced J2ObjC - October 2012, Googlers were late for 4 hours to our event; to fill the gap I had my fist talk about J2ObjC
  4. 5.

    With help of GetSocial SDK you can add Activity Feed,

    Chat, Notifications or Smart Invites just with a few lines of code
  5. 7.


    With over 50 integrated apps, GetSocial serve 30 million users every month that generated half a billion sessions during 2015.
  6. 8.


    Android Bridge C# API Unity SDK Java Objective C C# We have Android and iOS SDKs built natively using Java and Objective C respectively. Unity SDK is a thin bridge layer that forwards calls from public interface exposed in C# to native implementation
  7. 9.

    @zasadnyy GETSOCIAL SDK ARCHITECTURE THE GOOD: • easy to leverage

    all platform features • doing work twice • hard to keep in sync API behaviour THE BAD: The biggest advantage of having pure native SDK - being able to use low level platform features. Disadvantage - all features are implemented twice (longer time to market), also it’s hard to keep behaviour in sync, coz each developer has unique way to solve problems.
  8. 10.

    –Sun Microsystems WRITE ONCE, RUN EVERYWHERE “ We decided to

    look around on possible solutions, to reach ultimate goal, write code once and run it everywhere.
  9. 11.

    @zasadnyy J2ObjC Xamarin RubyMotion RoboVM We did a research on

    what tools were available on a market. Some were not performant enough, some were not suitable for SDK development.
  10. 12.

    @zasadnyy J2ObjC All except J2ObjC. Project started and actively developed

    by Google. Inbox built with J2ObjC. We started an internal RnD project to research if J2ObjC can fit with our requirements.
  11. 15.
  12. 16.

    @zasadnyy • NOT cross-platform application tool • NOT platform-independent UI

    toolkit • NOT Java emulator • NOT one time source translation WHAT J2OBJC ISN’T
  13. 19.

    @zasadnyy IS IT PRODUCTION READY? 25+ projects Google is using

    J2ObjC for almost all office apps. Besides Google, more than 25 projects claimed using J2ObjC.
  14. 20.

    @zasadnyy WHAT IS SUPPORTED? • Full Java 7 syntax •

    Inner classes, enums, annotations… • Reflection • OSNI code embedding J2ObjC engineers did a great job, they reimplemented Java paradigms like inner classes, enums, annotations and reflection on Objective C, where they are not available.
  15. 21.

    @zasadnyy OSNI CODE EMBEDDING static native void log(String text) /*-[

    NSLog(@"%@", text); 
 ]-*/; JAVA + (void)log: (NSString*)text {
 NSLog(@"%@", text); 
 } OBJECTIVE C You can embed Objective C code in Java in a special comments. DON’T do that, little bunnies die each time you’re using OSNI.
  16. 23.

    @zasadnyy HOW TO USE $ j2objc BigAndroidBBQ.java BASH • BigAndroidBBQ.java

    $ ls BigAndroidBBQ.h BigAndroidBBQ.m BASH translating BigAndroidBBQ.java Translated 1 file: 0 errors, 0 warnings j2objc is a command line tool, you’re going to work with to perform translation from Java to Objective C. It’s very powerful, but not very convenient to use on a real projects, coz amount of passed parameters will explode.
  17. 24.

    @zasadnyy AVAILABLE PLUGINS Make Maven Eclipse Gradle J2ObjC provide a

    plugins for most part of popular build tools. We’re going to focus on Gradle plugin.
  18. 25.

    @zasadnyy GRADLE PLUGIN • Easy integration • State of art

    codebase THE GOOD Bruno Bowden Advay Mengle • Rockstar authors
  19. 26.

    @zasadnyy GRADLE PLUGIN • As of July 25 is not

    supported • Last supported J2ObjC version is • Last supported Gradle version is 2.8 • Check our fork at https://github.com/getsocial-rnd/j2objc-gradle THE BAD Main problem with j2objc-gradle plugin - it supports only Gradle up to v2.8. Android on the other hand to support latest features requires 2.9+. Big part of plugin need to be rewritten to support new project model introduced in 2.9.
  20. 27.

    @zasadnyy SETTING UP IOS PROJECT • Automatically via CocoaPods •

    Manually link binaries THE GOOD: THE BAD: • Impossible debug
  21. 28.
  22. 29.


    Source Static Library Xcode Project Python Script
  23. 30.

    @zasadnyy BUILD TIME OPTIMISATIONS • Build only debug binaries •

    Include only target processor architectures Default: ios_arm64,ios_armv7,ios_x86_64 • Set up single platform builds
  24. 31.


    Source Static Library Xcode Project Python Script One more place where initially we planned to optimise - drop static library compilation, as we’re using only sources. But it didn’t work out, coz test translated to Objective C are executed on binaries.
  25. 34.

    @zasadnyy PROJECT STRUCTURE workspace ├── build.gradle ├── android │ ├──

    build.gradle │ └── src/... // only Android specific code ├── ios │ ├── IOS-APP.xcodeproj │ ├── Podfile │ ├── WORKSPACE.xcworkspace │ ├── IOS-APP/... │ ├── IOS-APPTests/... │ └── Pods/... └── shared ├── build.gradle // ‘j2objc' plugin configuration ├── lib/.. └── src/... // shared code for translation RECOMMENDED HIERARCHY
  26. 35.

    @zasadnyy PROJECT STRUCTURE workspace ├── build.gradle ├── android │ ├──

    android-demo/.. │ └── android-library/.. // Android platform dependant code ├── ios │ ├── ios-demo/.. │ ├── ios-library/.. // iOS platform dependant code │ ├── ios-shared │ └── WORKSPACE.xcworkspace ├── lib │ ├── rx-java │ └── gson └── shared ├── lib/.. // this lib folder is not used └── src/... GETSOCIAL CASE
  27. 38.

    @zasadnyy DEPENDENCY MANAGEMENT KEY POINTS • Sources required to cross

    compile libraries • Not all java packages implemented (missing java.nio and parts of java.security) • Tests are highly recommended
  28. 39.

    @zasadnyy DEPENDENCY MANAGEMENT HANDLED BY GRADLE PLUGIN dependencies { compile

    ‘com.google.code.gson:gson:2.6.2’ } shared/build.gradle j2objcConfig {
 autoConfigureDeps true
 } If OOS library has sources and test published together with a binaries, you can ask j2objc plugin to pull them and cross compile. But we managed to get it working only for Gson.
  29. 40.

    @zasadnyy DEPENDENCY MANAGEMENT MANUALLY workspace ├──... ├── lib │ └──

    rx-java │ └── build.gradle └── shared └── build.gradle 1. Set-up J2ObjC translation for library 2. Include library project More universal way is to create a new project with library, set up j2objc cross compilation for a project and include it as a dependency into shared module. 1 2
  30. 41.

    @zasadnyy Check ported libs at j2objc-common-libs-e2e-test GitHub project DEPENDENCY MANAGEMENT

    PORTED LIBRARIES Junit, Hamcrest, Mockito, Protobuf, Guava, Gson, Joda-time, commons-lang3, sqlighter-4 PORTED: AssertJ, RxJava, http libraries, DI, … MISSING:
  31. 44.

    @zasadnyy TESTING • JUnit 3, 4 • Hamcrest 1.3 •

    Mockito 1.9.5 THE GOOD: TOOLCHAIN
  32. 45.

    @zasadnyy TESTING • Narrow selection of testing libs/frameworks • Util

    classes in tests are being executed => FAIL • Thread.sleep(0) hangs THE BAD The easiest way to solve the problem with util classes being run as test is to agree on convention of Test suffix for all text classes + providing exclude pattern for tests in j2objc grade plugin config
  33. 46.

    @zasadnyy NAME MANGLING package com.zasadnyy.reddit.model; public class RedditDataManager {…} RedditDataManager.java

    @interface ComZasadnyyRedditModelRedditDataManager : NSObject RedditDataManager.h Translates to CLASS NAMES Check the demo repo for more examples
  34. 48.

    @zasadnyy NAME MANGLING THE GOOD j2objcConfig {
 translateArgs '--prefixes', 'packagePrefixes.properties'

    translateArgs '--mapping', 'methodMapping.properties'
 } shared/build.gradle Method/package mapping configurations Gradle plugin provides configuration closure to setup package and method names mappings
  35. 49.

    @zasadnyy NAME MANGLING THE BAD RedditDataManager.init(Ljava/lang/String;)V = VzRedditDataManager initWithAppId:(NSString)appId mapping.properties

    Method mappings are fragile Any refactoring of the method or change in package mappings will break your method mapping configuration
  36. 50.

    @zasadnyy NAME MANGLING GETSOCIAL SOLUTION Package prefixes Set of wrappers

    + We ended up using package mapping + wrapping all generated code on the ObjC side
  37. 52.

    @zasadnyy PERFORMANCE Make simple computations on the array of 600

    GPS coordinates 1,000 times Testing method: COMPUTATIONAL Source: Medium post by Harry Cheung
  38. 53.

    @zasadnyy PERFORMANCE COMPUTATIONAL Average iOS Computational Performance Swift 1.2 J2ObjC

    J2ObjC (ARC) Xamarin RoboVM Time, s 0 0,275 0,55 0,825 1,1
  39. 54.

    @zasadnyy PERFORMANCE Make simple computations on the array of 600

    GPS coordinates 10,000 times Testing method: MEMORY Source: Medium post by Harry Cheung
  40. 55.

    @zasadnyy PERFORMANCE Peak iOS Memory Performance Swift 1.2 J2ObjC J2ObjC

    (ARC) Xamarin RoboVM RubyMotion Usage, Mb 0 5,5 11 16,5 22 MEMORY
  41. 56.

    @zasadnyy IOS APP SIZE IMPACT 3Mb Extra (1 target platform)

    Reduce size: • Include only required parts of jre_emul.a • Shrink unused Java code with Proguard 3Mb is mainly a size of translated JRE library that should be included with your project.
  42. 57.

    @zasadnyy TEAM IMPACT • iOS Developers have way less work

    • Developers should be familiar with both platforms
  43. 58.

    @zasadnyy AT A GLANCE J2ObjC is an evolution of idea

    of cross platform development. For Google it works quite good. For GetSocial J2ObjC solved most part of problems we had. On the other hand we got a bunch of problems and challenges related to grade plugin support and some minor issues in the translator. Is it going to work for you? Before using any tool you should always check if it applicable in your particular case. To sum up, don’t be afraid to play with new tools, experiment, fail, try again, find your silver bullet solutions and absolutely go cross-platform. Thank you.
  44. 61.

    @zasadnyy RESOURCES • Official J2ObjC website • J2ObjC on GitHub

    • J2ObjC Gradle Plugin on GitHub • GitHub project with end-to-end test of compatible libraries • Goodow GitHub account with several J2ObjC related repos • Cross platform frameworks performance tests • Demo project