This article describes our journey being the first team to run Kotlin in the backend at ING (Netherlands). Hopefully this article will give you some keys on how to introduce it as well in your own large company, and reduce some of the friction you might encounter.
At ING, we are always trying to find new ways to iterate faster, be more productive and also keep our engineering skills sharp. As you may already know, the large majority of our back-end applications are written on top of the JVM. That means Java and some Scala. Haven’t heard about any team running Clojure yet :). Even though Java 8 is still supported until March 2022, our team wanted to move forward and not have to play the catch up game later. We looked into upgrading to Java 11+, but not all of the tooling has upgraded yet. It also looked like a challenging task in the short term. At the same time, we saw Kotlin make its way into more and more projects outside of the company. Inside as well actually, as our Android teams are already on Kotlin for a while.
Our team has been getting more and more into Functional Programming in the past years. Not the pure type, but the pragmatic type. Having immutable data classes, exhaustive pattern matching, or map/reduce constructions as first class citizens bring peace of mind, and make it easier to reason with our logic. Our side-projects written in Elm the last year made it obvious. We started discussing about moving to Scala. But Scala can be a little scary for the average developer, as the syntax can be intimidating. We also didn’t like the fact that there always seems to be many ways to do one thing in Scala, and we didn’t want to get stuck in endless design discussions. We wanted the rest of our team to WANT to work with us, not fight to get Java back. Last but not least, we saw the Scala 3 upgrade coming and having both been scared by the Python 2 / 3 split we wanted to avoid it.
This is why Kotlin seduced us : a simple but clear syntax, a growing adoption, and most importantly only a couple hours needed to move to from a Java background.
Now we had a goal in mind : start writing Kotlin every day. But how hard would it be to reach that objective?
Our journey started one evening. We had one hour left before the weekend. What was the smallest step we could take to introduce Kotlin in our codebase? Rewriting the whole app was of course no solution, so we knew only new code would be written in Kotlin for the years to come. Kotlin compiles to bytecode, and is meant to play well with Java, so we weren’t really afraid to just start writing Kotlin. Our worry was more the deliverable and the deployment of our artifacts. Writing a new feature in Kotlin would test two things at once : Kotlin code in production, and our ability to write Kotlin. We wanted to test only one! So we decided to convert the smallest POJO we could find to Kotlin and push that single change to production. No functionality change. Only those two lines of Kotlin!
This is how it looked like (and as you can witness, it’s pretty magic!). We picked our POJO and went for the Convert Java class to Kotlin feature from the Intellij IDEA. Now suddenly a lot of cool things happen!
This is the resulting class
NOTE: The auto refactor tool from Intellij is useful for trivial POJOs, but do expect to have to refactor and fix issues if you try to convert more complex classes.
Intellij will detect Kotlin code and offer in a blue ribbon at the top of the screen to update our POM automatically, which we gladly accept!
Which results in the following additions:
Intellij then detects Kotlin in our POM, and offers to install (or update, in our case) the kotlin runtime automagically. Yes please!
And as a last goodie, we can now remove Lombok from our imports!
Well, that’s it. We now have Kotlin in our application. And since we deploy a fat jar, we can simply re-run $mvn clean install and be done :). Took us 20 minutes, including compilation. One of those Fridays where you can go and have a drink earlier, thanks a lot Intellij!
Note: In case you get [ERROR] MyClassLinkingKotlin.java:[100,40] error: cannot find symbol errors, have a look at this Stack Overflow answer
As quickly mentioned above, deploying is actually not a large problem in case you’re already deploying fat jars or war files, because Kotlin will simply compile to compatible bytecode, and your application will just work. Still, it was important for us to make sure of that so we deployed this single change to production using our usual pipeline. No issues on the horizon, since our deployment pipeline did not need any extra tools other than one more maven dependency. We were on production the next day, with Kotlin code, and no problem detected in the logs or on the dashboard. Smooth sailing.
We work in a bank. In our environment, staying secure and compliant is paramount because it can have huge consequences. Compliancy and Security were (and maybe are in your context as well) actually our largest worries. Pentests and vulnerability management are not a problem, because we didn’t change our process at all. Now, as a team we are also required to have all of our source code reviewed for security flaws. In a Java context, that means have it passed through a Fortify scan, correct any issues that come up and have it validated by our security teams.
Now, Fortify happens to not be compatible with Kotlin code, so we looked for other solutions
- In the short term, we requested for manual security code reviews. Our team member Hielke de Vries, a former pentester, further helped negotiating with the security departments to find a solution for Kotlin code.
- Then we looked into Checkmarx, which added Kotlin support from version 8.9.0. Joy! In addition, it was already used in the bank by other teams! Unfortunately, we found out the Kotlin support meant Kotlin for Android , and not Kotlin backend :(.
- After further investigation, Hielke dived into the FindSecBugs security scanner and its maven / gradle plugins. Findsecbugs checks your code for security bugs (including Kotlin) and presents its findings in a report.
After some discussions, our security teams agreed to this format and the report can now be used as proof for our Kotlin code, while our Java code keeps being reviewed using Fortify. We will still go through manual reviews once in a while, but it’s only healthy given the fact that we are a banking application :).
The process is quite simple. We use the spotbugs-maven-plugin with the following filter file:
and modify our pom.xml as such :
You can now run mvn spotbugs:check to scan for security issues for bugs and let the build fail if bugs are found, and generate an XML report. The most desired security report can be found in target/spotbugs.xml.
This was our last, and largest technical barrier. We now know how to write Kotlin code while staying compliant and secure. Our team now writes all of its new backend code in Kotlin, as well as refactorings. Our ‘legacy’ and existing code will stay in Java for the foreseeable future though, we won’t bring everything to a halt to convert everything.
Though we do have freedom to use our own tools at ING, spreading Kotlin inside the bank is not an easy job. Why would you use Kotlin when you can do Scala?. Scala is perfect for some use cases inside the bank. Streaming applications for example, or those with complex orchestration issues to solve like Baker for example. But let’s be honest, this is not the case for a large share of what we do. Our direct debits application has to work, and does get constant traffic, but it is also not inherently complex. And as mentioned before, Kotlin has a much lower initial cost to get teams started on it. At least that’s our belief :).
Because our application has been stable for a long time, and we tested our change in a controlled environment, we decided to be our own guinea pigs. Before advocating Kotlin everywhere, we wanted to be sure that it could work. For this, we deployed our POJO upgrade without mentioning it to more than direct management. And when all risks have been mitigated only have we started advocating for larger usage :). Test your own hypothesis first, in a controlled environment. And use metrics to know if everything went according to plan.
Even though it might be obvious for both of us why Kotlin made sense, and it was rather easy to get the rest of our team to ride along with us; we knew we still had a large share of the work before us. Early discussions about moving to Kotlin with our managers were met with lots of questions, and a little bit of skepticism.
Here are some of the questions that we heard, and how we answered them :).
- If we allow Kotlin today, won’t people want to do Haskell or Typescript tomorrow?
Well it’s great news that our engineers want to try new things. We need to align on what is and what is not OK. All our tools revolve around Java, but by extension the JVM. So we suggest to allow any JVM based language for teams, as it still allows for code sharing, … without generating new risks.
- How can we hire people that know Kotlin? Won’t it be hard for the market?
Nope, it won’t because we can keep hiring Java Devs. Even more so, we have a higher chance to keep our current engineers if we make them happy!
- Can’t Kotlin die tomorrow?
We also keep a Confluence page up to date with our latest findings regarding the language, and keep an eye on how things are developing to be aware of any upcoming problem.
On top of the written reports that can be found online, it definitely helps to hear from people with first hand experience. It allows people to ask their burning questions, but also get a larger view on how things are going. When trying to introduce Kotlin in the bank, we used some of the internal Meetups we organize to gather Subject Matter Experts, and make sure that key people that had to ride with us would be present :).
Concrete examples are the visit of Trisha Gee from Jetbrains last year who could answer some of the questions, Paulien van Alst (developer at OpenValue ) who came to present a Kotlin talk at our backend summit, or Joris Portegies Zwart (CTO of Ximedes ) who came over and talked about their experience with Kotlin. Ximedes works regularly with banks and even wrote a blog about how they switched to Kotlin as language of choice for all of their projects.
We also made sure to promote external events involving Kotlin when needed. All those initiatives helped convince decision takers as well as other engineers, and maybe even get them a little excited, about Kotlin and what it had to offer.
One of the GREAT things with Kotlin is that even though it brings a lot of value to teams, it is very easy to start with a Java background. You can start small, and move further and further as you learn the language. Jetbrains recognizes this, and they have a good Kotlin for Java developers course that can be done in a few hours and bring you up to speed with the specificities of the language. We also invested in a few books and generic knowledge of the language that we try to spread at time goes. One of the things that helped a lot last year was Advent Of Code: hearing us talk about Kotlin almost daily at the office a lot of our colleagues decided to use AOC as a crash course on Kotlin. In two weeks, we will livestream the KotlinConf talks at the office and participate with whoever is interested. Moreover, we make sure to be active on the Kotlin internal Mattermost channel, try to answer people’s questions and generally provide helpful support to whoever shows interest. Finally, we organize workshops to help people Get your app to Kotlin in 1/2 day to sort out the early issues that can occur.
As an engineer in a large organization, you cannot do much without management support. If you are spearheading, one of the things you will definitely need is a champion (or more!). One person that will support your choices, will give you the room to succeed or fail and will put part of his person on the line to help you achieve these objectives. Luckily those champions have not been hard to find for us. Our direct N+1 decided to support us in trying kotlin, provided that we were not putting the bank in any kind of risk, and our N+2 is always very interested to learn about any low hanging fruits (or not) that allow to rise productivity. Thanks to that direct support, we have been able to move forward fast and concentrate our efforts on the technical side of things. Note that it is much easier to find champions if you have successfully done all the steps mentioned above, and have a track record of success :).
All in all, it took us almost a year to really sort everything out in the details. We had some Kotlin on production in less than a year, but actually creating an ecosystem where any team can start doing Kotlin in the bank took some more work than expected. And as you can imagine, most of the work was not related to code, but making sure that all is in place to fulfill all requirements and ensure we can stay compliant. The outcome is rewarding though, not only are we implementing all of our new features in Kotlin, but we have also made other people excited about what’s coming! Teams already interested can walk in our footsteps and reuse the policies we have proposed and that were accepted. We see a great future for Kotlin at ING, and we are just the beginning!
If you have questions or just want to discuss about the article, feel free to contact me or Hielke de Vries. We went through the journey, and wrote the article together and would love to hear from you!