Category:

Hootsuite’s Android team adopted Kotlin in the first half of 2016 as an alternative programming language to Java. We immediately loved it. Within a few months, one of our developers wrote a blog post raving about Kotlin idiomatic code. Now that Kotlin is an officially supported language for Android, we’d like to share our story of nurturing the growth of Kotlin in Hootsuite. Adopting a new language in a mature brownfield project requires a group of passionate individuals willing to take on a significant risk and be accountable everyday.

First Encounter and Case to Adopt

It was February 2016. Jetbrains had just released Kotlin v1.0 and one Android (and Scala) developer sent out Jake Wharton’s (1 year old) proposal for Project Kotlin for Android. The whole Android team met to discuss every point in the proposal, weighing null safety, higher order functions, and technical JVM details with alternative technologies along with the risks of adopting a new language. Surely, this proposal was all that was needed to convince everyone on the team? Nope, and rightly so. We already had RxJava and Retrolambda to bring streaming, concurrency and lambdas.

It was by another presentation from Jake Wharton, Advancing Development with Kotlin, that, in tandem with his first proposal, challenged us to Build a Better Way and #BSU. From here, a few of us on the team worked out a plan to get the ball rolling:

  1. Communicate and get buy-in from our Development Directors
  2. Schedule dedicated training sessions
  3. Dip a small toe (code) into the Kotlin waters
  4. Identifying and mitigating operational risks

Getting Buy-in

Most technologies that we adopt and use at Hootsuite originally start off as ideas from the development teams. The journey to successfully adopt Scala and Go required many groups in the organization to overcome varied challenges: deployment infrastructure, DevOps practices, build pipelines, developer tooling amongst others. Beyond developers, changes were made in hiring talent and training developers. Adopting Kotlin was just embarking on a new journey.

In our case of the Android platform in February 2016, the answer to “What does Google think?” was silence. The strongest individual backing of Kotlin came from JetBrains, the company behind the Kotlin language. Andrey Breslav, Lead Language Designer, made this statement on JetBrains’ usage of Kotlin :

“At JetBrains, we’ve not only been implementing the compiler and tooling but have also been using Kotlin in real-life projects on a rather extensive scale over the last two years.”

Andrey Breslav on Kotlin 1.0 Release (Feb 2016)

In the community, Hadi Hariri in the Fragmented Podcast mentioned how amazing it was that the Android community has adopted and supported Kotlin, with special thanks to the aforementioned essay by Jake Wharton. The community was vouching for its adoption.

I created a sample Android application and tested the major features, especially Java interop. If we could demonstrate a low risk for a sample brownfield project (Java, Dagger, Retrofit, RxJava, etc), there are high hopes we could bring it safely into our smaller projects. Our development director, took our proposal, considered the supporting information, asked critical questions regarding risks, and encouraged us to keep exploring.

Training Up in Kotlin

On Kotlinlang.org, Jetbrains encouraged new developers to either try Kotlin right in the browser, or work on exercises called Koans. At first, we played with the web interface to get a glimpse of the language syntax. As the end of February 2016 approached, we booked 1-hour study group sessions for all Android devs on Tuesday and Thursday after lunch. These sessions would focus specifically on working through each chapter in the Koans together with a partner to compare answers and approaches. After 8 study sessions (4 weeks), the team had gone through most of the exercises and was ready to try Kotlin in the app.

For any brand new users to Kotlin, I’d suggest playing with Kotlin from the browser first. When you get serious about developing in it, I would recommend to git clone the Koans, then work through the exercises using the IntelliJ IDE.

Kotlin Officially in Production

We wanted to introduce Kotlin in a small spot so we could isolate risks and validate development feasibility. In early 2016, our team was investing more into internal libraries to speed up development of features. It’s in these libraries that Kotlin would also make the most impact, by enabling consuming apps to benefit from Kotlin features. Kotlin in these repositories was a crucible; if developers could consume libraries written in Java and Kotlin, in a Java only project, then developers would benefit, otherwise Kotlin would not fit our development model.

So in April 2016, I chose to officially introduce Kotlin into our core library by converting one Java class to Kotlin and introducing a new enum. That’s It! Our main Hootsuite app consumed this library and was able to use the class and enum from Java classes, as if those Kotlin classes were Java. Tests passed and regression tests found no issue. The seed was planted.

The rest of the team in the same week began committing with a mix of Java and Kotlin code. With every commit, each developer introduced simple pieces of Kotlin. We saw the introductions of POKOs (Plain Old Kotlin Objects), extension functions, injectable classes, custom android views, presenters (from Model-View-Presenter) and unit tests. As Kotlin was being used more, the team started using Kotlin for portions of new features, Team Collaboration with Message Approvals for example.

In July 2016, the Android team released a feature fully written in Kotlin, called Compose Feedback. Originally, Kotlin played only a supporting role to Java, defining model classes, enums and interfaces. As the entire team was ramping up on Kotlin, the team felt that it was a safe opportunity to put Kotlin fully into production. The team converted Java code to Kotlin and refined the generated Kotlin to use Nullable types with Elvis operators, Kotlin standard library functions and Named Arguments.

When the Compose Feedback feature was released and demoed to developers, our team also announced to the broader Hootsuite developer community that we had been adopting Kotlin for development, and that this feature was our effort to prove Kotlin was ready for production.

Operational Risks

To adopt Kotlin and keep Kotlin running well in production, and eventually into prominence, we asked and were asked these questions:
  1. What is the learning curve of Kotlin and how do we lower the barrier of entry for others who want to contribute to our project?
  2. What would impact our ability to develop and deliver projects on a day-to-day?
  3. How will Kotlin impact our ability to hire talent for our team?
  4. How do we ensure our risk exposure doesn’t grow while we see how Google responds to Kotlin in general?

Learning Curve

Our opportunities to learn Kotlin were limited in early 2016; we only had videos and articles from early adopters. The Kotlin Koans, from JetBrains, was and continues to be our go-to place to learn Kotlin and its features. To lower the barrier of entry, we created an onboarding session for new developers and worked closely with each of them as they developed their first features in Kotlin.

Issues coming from Development and Building

Introducing Kotlin to the codebase also brings with it the Kotlin compilation step whenever a build to device or unit tests are done. It was during the build process that we ran into some issues.

When we first introduced Kotlin, the build time increases were minor and trivial. We had very few Kotlin files to compile. As more Java code was converted to Kotlin and new Kotlin files were created, the build times slowly creeped up to several minutes, like others. With incremental compilation added to Kotlin through Gradle in 1.0.2, we experienced some improvements. Sure, it would be nice to convert our project to 100% Kotlin to mitigate long build times, but we didn’t have that luxury. We were stuck with the compileDebugKotlin, compileDebugJavaWithJavac, compileDebugKotlinAfterJava gradle build steps.

At Hootsuite, we are proponents of the Library Oriented Programming approach to facilitate rapid development. As such, we adopted Kotlin into a number of our many libraries. Issues surfaced when different versions of Kotlin (1.0.2, 1.0.3-1, 1.0.3-5, etc) were distributed amongst our libraries. When built into our main app, we would often receive an error while compiling. The solution we employed after some failed attempts to try to understand the problem was to always align the Kotlin versions in all libraries.

One specific issue we were forced to work around on several occasions was in ProGuard. While Proguard had no problem evaluating literals, variables or exceptions in the null position of the Elvis operator (?:), it would fail when the null case was an expression with or without operations.

In the above Gist, Proguard would fail trying to evaluate ?: doubleup(a) portion. This issue can be found in project Anko, where they suggest the bug from Proguard either forces a change to Anko, or to not optimize in Proguard.

We’ve found other weird build issues in 2016 that we worked past. Usually, our team found a solution by talking to other Kotlin devs in slack and after a lot of trial and error. Sometimes, we chose to keep the code as Java and circle back later. It meant picking the right problems to fix based on their necessity in our product.

Kotlin a Bonus in Finding Talent

When it came to hiring Android developers, our job postings in 2016 didn’t mention Kotlin until later in the year. As development in Kotlin picked up on the team, we observed that developers new to the language were ready to code in Kotlin after 2 weeks, and after 1-2 months, were contributing code that effectively used Kotlin features. Developer happiness was high and each demonstrated that Kotlin wouldn’t be a barrier to write great code.

In the 2nd half of 2016, we started mentioning Kotlin in our job postings as a bonus. To this day, most candidates that we interview don’t know much about Kotlin. But whenever we mention that we are invested in using Kotlin, candidates show genuine interest in how positive it has been in our development and ask about the technical hurdles we had encountered.

Bringing Kotlin into Prominence

Our team at Hootsuite worked hard in the first six months to get the Kotlin ball rolling and build momentum. Within six months, the core Android team had fully adopted Kotlin as the primarily language. One year later, in 2017, all new features and code are written in Kotlin. Building momentum was more than just working through Koans and trying features; it required our consistent drive to push ourselves to learn and adopt more idiomatic Kotlin practices.

I highly recommend you come back for our next blog post from Neil Power on how the Android team grew Kotlin to be the primary language for development, and how we have kept the interest of Kotlin alive in Hootsuite and in our Vancouver dev community.

 

About the Author

Simon TseSimon Tse is an Development Manager on the mobile team at Hootsuite. He enjoys testing the limits of new technologies and ideas in his apps. Follow him on Twitter @simtse.

How do we share our libraries internally?

In 2015, our Android team released v3 of Hootsuite’s app with a new UI following Material Design guidelines. We also gave users the Publisher feature, Instagram integration and enhanced Twitter Search. The development of these features relied on many popular open source libraries and tools, such as RxAndroid, Retrofit, Google Design, Robolectric, and many more. With the success of these libraries, our Android development team was inspired to build our own libraries to allow other teams to consume. A great idea, with a surprising complication: How do we share our library internally?

Publishing libraries to Maven Central using Gradle has been covered before by Chris Banes and others. His solution is visualized in the following diagram.

Chris Banes Maven Gradle

Our need was to be able to publish libraries to a private Maven repository like Artifcatory. We tweaked @chrisbanes‘s solution and made it available to our developers to enable them to write libraries independently and share them between teams.

Hootsuite Maven Gradle

In this post, I’m going to guide you in setting up your library to share your own Maven repository.

The Template Library Project

Most Android library projects share a similar directory structure, so we prepared a Library Template that will act as the reference for this guide. We encourage you to fork this project if you’re starting fresh.

Read More …