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

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
Tweet

More Decks by Vitaliy Zasadnyy

Other Decks in Technology

Transcript

  1. @zasadnyy
    The good, the bad and the ugly
    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. @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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

  8. @zasadnyy
    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

  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.

    View Slide

  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.

    View Slide

  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.

    View Slide

  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.

    View Slide

  13. DIVE INTO J2OBJC
    Let’s look more close on the key features of J2ObjC.

    View Slide

  14. J2ObjC - WTF?
    Build configuration
    Development process
    Project impact
    THE GRAND PLAN
    @zasadnyy

    View Slide

  15. @zasadnyy
    WHAT IS J2OBJC?
    • Source-to-source compiler
    • Focus on shared business logic
    • Apache 2 Licence

    View Slide

  16. @zasadnyy
    • NOT cross-platform application tool
    • NOT platform-independent UI toolkit
    • NOT Java emulator
    • NOT one time source translation
    WHAT J2OBJC ISN’T

    View Slide

  17. @zasadnyy
    IS IT PRODUCTION READY?
    v1.0.0
    January 21, 2016

    View Slide

  18. @zasadnyy
    IS IT PRODUCTION READY?

    View Slide

  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.

    View Slide

  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.

    View Slide

  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.

    View Slide

  22. @zasadnyy
    BUILD CONFIGURATION

    View Slide

  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.

    View Slide

  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.

    View Slide

  25. @zasadnyy
    GRADLE PLUGIN
    • Easy integration
    • State of art codebase
    THE GOOD
    Bruno Bowden Advay Mengle
    • Rockstar authors

    View Slide

  26. @zasadnyy
    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

  27. @zasadnyy
    SETTING UP IOS PROJECT
    • Automatically via CocoaPods
    • Manually link binaries
    THE GOOD:
    THE BAD:
    • Impossible debug

    View Slide

  28. @zasadnyy
    SETTING UP IOS PROJECT
    DEFAULT FLOW
    Java
    Source
    ObjC
    Source
    Static
    Library
    Xcode
    Project

    View Slide

  29. @zasadnyy
    SETTING UP IOS PROJECT
    GETSOCIAL SOLUTION
    Java
    Source
    ObjC
    Source
    Static
    Library
    Xcode
    Project
    Python
    Script

    View Slide

  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

    View Slide

  31. @zasadnyy
    SETTING UP IOS PROJECT
    GETSOCIAL SOLUTION
    Java
    Source
    ObjC
    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.

    View Slide

  32. @zasadnyy
    BUILD TIME OPTIMISATIONS
    GETSOCIAL CASE
    6
    min
    <2
    min
    *Android + J2ObjC build

    View Slide

  33. @zasadnyy
    DEVELOPMENT PROCESS

    View Slide

  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

    View Slide

  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

    View Slide

  36. @zasadnyy
    J2OBJC ENFORCES CLEAN
    ARCHITECTURE
    THE GOOD

    View Slide

  37. @zasadnyy
    Presentation
    CLEAN ARCHITECTURE
    Drivers
    Frameworks
    Domain
    Dependency
    Rule
    shared
    XXX-library
    XXX-demo

    View Slide

  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

    View Slide

  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.

    View Slide

  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

    View Slide

  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:

    View Slide

  42. @zasadnyy
    UNIT TESTING IS THE DNA OF
    J2OBJC
    THE GOOD

    View Slide

  43. @zasadnyy
    HIGH TEST COVERAGE IS THE
    ONLY WAY TO CONFIDENCE
    THE BAD

    View Slide

  44. @zasadnyy
    TESTING
    • JUnit 3, 4
    • Hamcrest 1.3
    • Mockito 1.9.5
    THE GOOD: TOOLCHAIN

    View Slide

  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

    View Slide

  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

    View Slide

  47. @zasadnyy
    NAME MANGLING
    String foo(int i);
    JAVA
    - (NSString *)fooWithInt:(jint)i;
    OBJECTIVE C
    Translates to
    METHODS

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  51. @zasadnyy
    PROJECT IMPACT

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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.

    View Slide

  57. @zasadnyy
    TEAM IMPACT
    • iOS Developers have way less work
    • Developers should be familiar with both platforms

    View Slide

  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.

    View Slide

  59. @zasadnyy
    AT A GLANCE
    Maintainability
    Performance
    Size footprint Apache 2 License

    View Slide

  60. Thank you!
    Questions?
    Vitaliy Zasadnyy
    @zasadnyy
    Slides will be available at:
    v.zasadnyy.com/slides/
    DANK JE

    View Slide

  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

    View Slide