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

J2ObjC. The silver bullet in cross-platform mobile development

J2ObjC. The silver bullet in cross-platform mobile development

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 us, as mobile developers, it means that all further projects should target at least two platforms. Main products we are working on at GetSocial are 3 SDKs for Android, iOS and Unity. All libraries have the same functionality and feature rich UI. In this talk, I want to share results of our internal RnD experiments 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

February 18, 2016
Tweet

More Decks by Vitaliy Zasadnyy

Other Decks in Programming

Transcript

  1. #MobOS2016
    The silver bullet in cross-platform mobile development
    J2ObjC
    Vitaliy Zasadnyy
    Head of Mobile @ GetSocial February 18-19, 2016, Cluj

    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. #MobOS2016
    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, Unity and iOS

    View Slide

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

    View Slide

  8. #MobOS2016
    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. #MobOS2016
    GETSOCIAL SDK ARCHITECTURE
    PROS & CONS
    • easy to leverage all platform features
    PROS:
    • doing work twice
    • hard to keep in sync API behaviour
    CONS:
    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. #MobOS2016
    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

  12. #MobOS2016
    CROSSPLATFORM TOOLS

    View Slide

  13. #MobOS2016
    Xamarin
    Pros: proven technology, big community, access to UI
    API from Xamarin
    Cons: it’s not possible to build SDK with Xamarin and
    use with native apps; paid solution

    View Slide

  14. #MobOS2016
    RubyMotion
    Very similar approach to Xamarin, but you have to use
    Ruby

    View Slide

  15. #MobOS2016
    RoboVM
    The most recent tool made by startup based in
    Finland.
    Pros: you can use any JVM language, code is cross
    compiled to iOS machine code => fast, gives access to
    UI API
    Cons: very early stage, no big apps using it, paid
    solution

    View Slide

  16. #MobOS2016
    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

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

    View Slide

  18. #MobOS2016
    WHAT IS J2OBJC?
    • Source-to-source compiler
    • Focus on shared business logic
    • Apache 2 Licence

    View Slide

  19. #MobOS2016
    • 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. #MobOS2016
    IS IT PRODUCTION READY?
    v1.0.0
    January 21, 2016

    View Slide

  21. #MobOS2016
    IS IT PRODUCTION READY?

    View Slide

  22. #MobOS2016
    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

  23. #MobOS2016
    WHAT IS SUPPORTED?
    • Full Java 7 syntax
    • Inner classes, enums, annotations…
    • Reflection (almost all)
    • 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

  24. #MobOS2016
    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

  25. #MobOS2016
    HOW TO USE
    $ j2objc Romobos.java
    BASH
    • Romobos.java
    $ ls
    Romobos.h Romobos.m
    BASH
    translating Romobos.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. #MobOS2016
    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

  27. –Linus Torvalds
    TALK IS CHEAP.
    SHOW ME THE CODE

    View Slide

  28. DEMO IS AVAILABLE ON GITHUB
    Links on the SpeakerDeck are not clickable, so:
    https://github.com/zasadnyy/j2objc-reddit-prototype

    View Slide

  29. #MobOS2016
    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

  30. #MobOS2016
    NAME MANGLING
    String foo(int i);
    JAVA
    - (NSString *)fooWithInt:(jint)i;
    OBJECTIVE C
    Translates to
    METHODS

    View Slide

  31. #MobOS2016
    NAME MANGLING
    MAKE IT READABLE
    Option 1:
    Create a Facade class to wrap public interface
    During cross compilation some Java classes are
    mapped to analogues on ObjC side, e.g. String =>
    NSString.
    But not all, e.g. ArrayList => JavaLangArrayList. Most
    part of JRE classes are translated so on ObjC side
    developer forced to work with Java-like interface. And
    it’s very inconvenient.
    Solution: provide a facade for a public interface.

    View Slide

  32. #MobOS2016
    NAME MANGLING
    MAKE IT READABLE
    Option 2:
    Provide method/package mapping configurations
    Partially you can solve problem by providing package/
    method name mapping.
    In reality you’ll use combination of two approaches.

    View Slide

  33. #MobOS2016
    NAME MANGLING
    MAKE IT READABLE
    j2objcConfig {

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

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

    }
    shared/build.gradle
    Provide method/package mapping configurations

    View Slide

  34. #MobOS2016
    JAVA RUNTIME ENVIRONMENT
    • Based on Android JRE
    • Almost 2000 classes ported
    • iOS-specific native code
    • Covered with over 4K Unit test
    THE JRE_EMUL PROJECT
    soon…

    View Slide

  35. #MobOS2016
    UNIT TESTING IS DNA
    • JUnit 3, 4 supported
    • Harmcrest 1.3
    • Mockito 1.9.5
    J2ObjC approach to validate generated code
    One the first features of J2ObjC was ability to translate
    Unit tests.

    View Slide

  36. #MobOS2016
    MEMORY MANAGEMENT
    There is no garbage collector on Objective C
    Solution approaches:
    • Reference Counting
    • ARC

    View Slide

  37. #MobOS2016
    MEMORY MANAGEMENT
    REFERENCE LOOPS
    R
    B
    A

    View Slide

  38. #MobOS2016
    MEMORY MANAGEMENT
    REFERENCE LOOPS
    R
    B
    A
    Java: no references from
    root => kill A and B

    View Slide

  39. #MobOS2016
    MEMORY MANAGEMENT
    REFERENCE LOOPS
    R
    Objective C: ref count != 0, so keep
    A and B in memory
    B
    A
    REF COUNT = 1
    REF COUNT = 1

    View Slide

  40. #MobOS2016
    MEMORY MANAGEMENT
    REFERENCE LOOPS
    • Cycle Finder Tool
    • @Weak and @WeakOuter annotations
    Provided tools:

    View Slide

  41. WHAT DOES IT MEAN TO
    MY PROJECT?

    View Slide

  42. #MobOS2016
    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

  43. #MobOS2016
    PERFORMANCE
    COMPUTATIONAL
    Average iOS Computational Performance
    Swift 1.2
    J2ObjC
    J2ObjC (ARC)
    Xamarin
    RoboVM
    RubyMotion
    Time, s
    0 7,5 15 22,5 30
    RubyMotion is slow a hell. Let’s drop it from the graph.

    View Slide

  44. #MobOS2016
    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
    J2ObjC is more performant than Swift.

    View Slide

  45. #MobOS2016
    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

  46. #MobOS2016
    PERFORMANCE
    Peak iOS Memory Performance
    Swift 1.2
    J2ObjC
    J2ObjC (ARC)
    Xamarin
    RoboVM
    RubyMotion
    Usage, Mb
    0 5,5 11 16,5 22
    MEMORY
    Regarding memory performance is more or less similar
    to Swift.
    RoboVM is doing some magic:)

    View Slide

  47. #MobOS2016
    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

  48. #MobOS2016
    ARCHITECTURE
    FOLDER 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
    ├── build/.. // generated build folder
    ├── lib/..
    └── src/... // shared code for translation

    View Slide

  49. #MobOS2016
    ARCHITECTURE
    GETSOCIAL FOLDER STRUCTURE
    workspace
    ├── build.gradle
    ├── android-client // only presentation code
    │ └── …
    ├── android-library // platform dependant implementations
    │ └── …
    ├── ios
    │ └── …
    └── shared
    └── …

    View Slide

  50. #MobOS2016
    UI
    ARCHITECTURE
    Implementation
    Domain
    CLEAN ARCHITECTURE
    Dependency
    Rule
    Using J2ObjC forces you to have a nice “clean”
    architecture. Learn more…

    View Slide

  51. #MobOS2016
    TESTING
    High test coverage is a key to code confidence

    View Slide

  52. #MobOS2016
    MISSING: AssertJ, RxJava, http libraries, DI, …
    • Only few 3rd party libraries are ported
    PORTED: Junit, Hamcrest, Mockito, Protobuf, Guava,
    Gson, Joda-time, commons-lang3, sqlighter-4
    Check ported libs at j2objc-common-libs-e2e-test GitHub project
    LIMITATIONS

    View Slide

  53. #MobOS2016
    LIMITATIONS
    • Porting new libraries requires sources
    • Not all JRE is supported
    • Only Java 7 can be used
    • All team members should know iOS and Android
    • Only few 3rd party libraries are ported

    View Slide

  54. #MobOS2016
    IS IT THE SILVER BULLET?
    J2ObjC is an evolution of idea of cross platform
    development. For Google it works quite good.
    For GetSocial J2ObjC is pretty much a silver bullet, as it
    solves most part of problems we had.
    Is it a silver bullet 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

  55. Thank you!
    Questions?
    Vitaliy Zasadnyy
    @zasadnyy
    Slides will be available at:
    v.zasadnyy.com/slides/
    THANK YOU

    View Slide

  56. #MobOS2016
    RESOURCES
    • Official J2ObjC website: http://j2objc.org
    • J2ObjC on GitHub: https://github.com/google/j2objc
    • J2ObjC Gradle Plugin on GitHub: https://github.com/j2objc-contrib/j2objc-gradle
    • GitHub project with end-to-end test of compatible libraries:
    https://github.com/j2objc-contrib/j2objc-common-libs-e2e-test
    • Goodow GitHub account with several J2ObjC related repos: https://github.com/goodow
    • Cross platform frameworks performance tests: http://bit.ly/crossplatformTests
    • Demo project: https://github.com/zasadnyy/j2objc-reddit-prototype

    View Slide