Upgrade to Pro — share decks privately, control downloads, hide ads and more …

J2ObjC. Cross platform development - Google way

J2ObjC. Cross platform development - Google way

The presentation was given at: https://devfest.gdg.org.ua

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.

For mobile developers this means that all further projects should target at least two platforms. In this talk, Vitaliy wants to share results of internal R&D experiments at GetSocial with 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

September 10, 2016
Tweet

More Decks by Vitaliy Zasadnyy

Other Decks in Programming

Transcript

  1. Cross platform development - Google way
    J2ObjC
    Vitaliy Zasadnyy
    Head of Mobile @ GetSocial

    View Slide

  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 [email protected]

    View Slide

  3. #dfua
    hard
    Cross platform development is

    View Slide

  4. #dfua
    70%
    code reuse
    Source: Gmail Blog

    View Slide

  5. #dfua
    25+ projects
    Google is using J2ObjC for almost all office apps.
    Besides Google, more than 25 projects claimed using
    J2ObjC.

    View Slide

  6. Now I’m leading mobile department at Dutch startup
    GetSocial

    View Slide

  7. With help of GetSocial SDK you can add Activity Feed,
    Chat, Notifications or Smart Invites just with a few lines
    of code

    View Slide

  8. SDK is available for Android, iOS, Unity and Cordova

    View Slide

  9. 30M
    50+ 500M
    APPS & GAMES MONTHLY USERS TOTAL SESSIONS
    With over 50 integrated apps, GetSocial serve 30
    million users every month that generated half a billion
    sessions during 2015.

    View Slide

  10. #dfua
    GetSocial SDK architecture
    Android
    SDK
    iOS
    SDK
    iOS Bridge 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

    View Slide

  11. #dfua
    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.

    View Slide

  12. –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.

    View Slide

  13. #dfua
    Requirements
    Maintainability
    Performance
    Size footprint Licensing
    Requirements for the solution:
    - performance should be at least the same as on native
    - code should be easy to maintain (reliable toolchain)
    - SDK should keep reasonable size
    - ideally solution should be free and compatible with
    our distribution model

    View Slide

  14. #dfua
    J2ObjC
    Xamarin XmlVM
    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.

    View Slide

  15. #dfua
    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.

    View Slide

  16. #dfua
    Dive into J2ObjC
    Let’s look more close on the key features of J2ObjC.

    View Slide

  17. J2ObjC - WTF?
    Build configuration
    Development process
    Project impact
    The grand plan
    @zasadnyy

    View Slide

  18. #dfua
    What is J2ObjC?
    • Source-to-source compiler
    • Focus on shared business logic
    • Apache 2 Licence

    View Slide

  19. #dfua
    • NOT cross-platform application tool
    • NOT platform-independent UI toolkit
    • NOT Java emulator
    • NOT one time source translation
    What J2ObjC isn’t

    View Slide

  20. #dfua
    Is it production ready?
    v1.0.0
    January 21, 2016

    View Slide

  21. #dfua
    What is supported?
    • Full Java 7 syntax
    • Inner classes, enums, annotations…
    • Reflection
    • JUnit test translation
    • OCNI 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.

    View Slide

  22. #dfua
    OCNI code embedding
    static native void log(String text) /*-[
    NSLog(@"%@", text); 

    ]-*/;
    Java code
    You can embed Objective C code in Java in a special
    comments.

    View Slide

  23. #dfua
    OCNI code embedding
    static native void log(String text) /*-[
    NSLog(@"%@", text); 

    ]-*/;
    + (void)log: (NSString*)text {

    NSLog(@"%@", text); 

    }
    Translated code
    DON’T do that, little bunnies die each time you’re using
    OCNI.

    View Slide

  24. #dfua
    Build configuration

    View Slide

  25. #dfua
    How to use
    $ j2objc DevFest.java
    $ ls
    DevFest.h DevFest.m
    translating DevFest.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.

    View Slide

  26. #dfua
    Available plugins
    Make Eclipse Gradle
    Maven
    J2ObjC provide a plugins for most part of popular build
    tools.
    We’re going to focus on Gradle plugin.

    View Slide

  27. #dfua
    Gradle plugin
    • Easy integration
    • State of art codebase
    The good
    Bruno Bowden Advay Mengle
    • Rockstar authors

    View Slide

  28. #dfua
    Gradle plugin
    • As of July 25 is not supported
    • Last supported J2ObjC version is 0.9.8.2.1
    • 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.

    View Slide

  29. #dfua
    Setting up iOS project
    • Automatically via CocoaPods
    • Manually link binaries
    THE GOOD:
    THE BAD:
    • Impossible debug

    View Slide

  30. #dfua
    Setting up iOS project
    Xcode
    Project
    Default flow
    Java
    Source
    ObjC
    Source
    Static
    Library

    View Slide

  31. #dfua
    Setting up iOS project
    Xcode
    Project
    Java
    Source
    ObjC
    Source
    Static
    Library
    GetSocial solution
    Python
    script

    View Slide

  32. #dfua
    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

    View Slide

  33. #dfua
    6
    min
    <2
    min
    *Android + J2ObjC build
    GetSocial case
    Build time optimisations

    View Slide

  34. #dfua
    Development process

    View Slide

  35. #dfua
    Project structure
    workspace
    ├── build.gradle
    ├── android
    │ ├── android-demo/..
    │ └── android-library/..
    ├── ios
    │ ├── ios-demo/..
    │ ├── ios-library/..
    │ ├── ios-shared
    │ └── WORKSPACE.xcworkspace
    ├── lib
    │ ├── rx-java
    │ └── gson
    └── shared
    ├── src/..
    └── build.gradle
    Shared code
    GetSocial case

    View Slide

  36. #dfua
    Libraries sources
    Project structure
    workspace
    ├── build.gradle
    ├── android
    │ ├── android-demo/..
    │ └── android-library/..
    ├── ios
    │ ├── ios-demo/..
    │ ├── ios-library/..
    │ ├── ios-shared
    │ └── WORKSPACE.xcworkspace
    ├── lib
    │ ├── rx-java
    │ └── gson
    └── shared
    ├── lib/..
    └── src/...
    GetSocial case

    View Slide

  37. #dfua
    Project structure
    workspace
    ├── build.gradle
    ├── android
    │ ├── android-demo/..
    │ └── android-library/..
    ├── ios
    │ ├── ios-demo/..
    │ ├── ios-library/..
    │ ├── ios-shared
    │ └── WORKSPACE.xcworkspace
    ├── lib
    │ ├── rx-java
    │ └── gson
    └── shared
    ├── lib/..
    └── src/...
    iOS code
    GetSocial case

    View Slide

  38. #dfua
    Project structure
    workspace
    ├── build.gradle
    ├── android
    │ ├── android-demo/..
    │ └── android-library/..
    ├── ios
    │ ├── ios-demo/..
    │ ├── ios-library/..
    │ ├── ios-shared
    │ └── WORKSPACE.xcworkspace
    ├── lib
    │ ├── rx-java
    │ └── gson
    └── shared
    ├── lib/..
    └── src/...
    GetSocial case
    Android code

    View Slide

  39. #dfua

    View Slide

  40. #dfua
    J2ObjC enforces Clean Architecture
    THE GOOD

    View Slide

  41. #dfua
    Presentation
    Clean architecture
    Drivers
    Frameworks
    Domain
    Dependency
    Rule
    shared
    XXX-library
    XXX-demo

    View Slide

  42. #dfua
    Libraries
    • Sources required
    • Not all java packages implemented
    • Tests are highly recommended

    View Slide

  43. #dfua
    dependencies {
    compile ‘com.google.code.gson:gson:2.6.2’
    }
    j2objcConfig {

    autoConfigureDeps true

    }
    Libraries
    shared/build.gradle
    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.

    View Slide

  44. #dfua
    workspace
    ├──...
    ├── lib
    │ └── rx-java
    │ └── build.gradle
    └── shared
    └── build.gradle
    GetSocial solution
    Libraries
    Set-up J2ObjC
    translation
    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.

    View Slide

  45. #dfua
    Check ported libs at j2objc-common-libs-e2e-test GitHub project
    Junit, Hamcrest, Mockito, Protobuf, Guava,
    Gson, Joda-time, commons-lang3, sqlighter-4
    PORTED:
    AssertJ, RxJava, http libraries, DI, …
    MISSING:
    Libraries

    View Slide

  46. #dfua
    Unit testing is the DNA of J2ObjC
    THE GOOD

    View Slide

  47. #dfua
    High test coverage is the only way
    to confidence
    THE BAD

    View Slide

  48. #dfua
    Testing
    • JUnit 3, 4
    • Hamcrest 1.3
    • Mockito 1.9.5
    Toolchain

    View Slide

  49. #dfua
    • Narrow selection of testing libs/frameworks
    • Util classes in tests are being executed => FAIL
    • Thread.sleep(0) hangs
    Testing
    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

    View Slide

  50. #dfua
    Name mangling
    package com.zasadnyy.reddit.model;
    public class RedditDataManager {…}
    @interface ComZasadnyyRedditModelRedditDataManager
    : NSObject
    Translates to
    Class names
    Check the demo repo for more examples

    View Slide

  51. #dfua
    Name mangling
    String foo(int i);
    - (NSString *)fooWithInt:(jint)i;
    Translates to
    METHODS

    View Slide

  52. #dfua
    Name mangling
    The good
    j2objcConfig {

    translateArgs '--prefixes', 'packagePrefixes.properties'

    translateArgs '--mapping', 'methodMapping.properties'

    }
    • @ObjectiveCName(“”)
    • Method/package mapping configurations
    Gradle plugin provides configuration closure to setup
    package and method names mappings

    View Slide

  53. #dfua
    Name mangling
    The bad
    RedditDataManager.init(Ljava/lang/String;)V =
    VzRedditDataManager initWithAppId:(NSString)appId
    Method mappings are fragile
    Any refactoring of the method or change in package
    mappings will break your method mapping configuration

    View Slide

  54. #dfua
    Name mangling
    GetSocial solution
    Package
    prefixes
    Set of
    wrappers
    +
    We ended up using package mapping + wrapping all
    generated code on the ObjC side

    View Slide

  55. #dfua
    Project Impact

    View Slide

  56. #dfua
    Performance
    Make simple computations on
    the array of 600 GPS coordinates 1,000 times
    Testing method:
    Computational
    Source: Medium post by Harry Cheung

    View Slide

  57. #dfua
    Computational
    Average iOS Computational Performance
    Swift 1.2
    J2ObjC
    J2ObjC (ARC)
    Xamarin
    RoboVM
    Time, s
    0 0,275 0,55 0,825 1,1
    Performance

    View Slide

  58. #dfua
    Make simple computations on
    the array of 600 GPS coordinates 10,000 times
    Testing method:
    Source: Medium post by Harry Cheung
    Performance
    Memory

    View Slide

  59. #dfua
    Peak iOS Memory Performance
    Swift 1.2
    J2ObjC
    J2ObjC (ARC)
    Xamarin
    RoboVM
    Usage, Mb
    0 5 10 15 20
    Performance
    Memory

    View Slide

  60. #dfua
    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.

    View Slide

  61. #dfua
    Team impact
    • iOS Developers have way less work
    • Developers should be familiar with both platforms

    View Slide

  62. #dfua
    At a glance

    View Slide

  63. #dfua
    At a glance
    • Unsupported Gradle plugin
    • Limitations on dependencies
    • Unit tests as the only way to validate logic
    THE BAD:

    View Slide

  64. #dfua
    At a glance
    THE GOOD:
    • Performance
    • Maintainability
    • Reasonable size footprint
    • Apache License
    • Clean architecture

    View Slide

  65. #dfua
    64%
    code reuse
    At a glance

    View Slide

  66. Thank you!
    Questions?
    Vitaliy Zasadnyy
    @zasadnyy
    Slides will be available at:
    v.zasadnyy.com/slides/
    Дякую за увагу!

    View Slide

  67. #dfua
    We are hiring ninjas!
    • Android (UA/NL)
    • Golang (UA)

    View Slide

  68. #dfua
    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

    View Slide