Java to Kotlin, from today to the future

Wednesday, December 5, 2018

DEVOXX 2018 ended a while ago so it’s time to get myself busy again with writing this blog, about… you’ll never guess it... KOTLIN. Before you start boooooing and shouting “NOT AGAAAAAAAIN!”. This one is different from all the rest ! (Yeah I know, everyone says that.. don’t hate the player, hate the game). This blog continues to work further on a talk Paulien van Alst did on the fourth day of Devoxx 2018.

Last year I wrote a blog about Kotlin called “Is Kotlin the next big thing?”. A blog which was read a lot, one of the most read technical blogs on our website. So thank you all for reading and I hope this one gets as much attention as my previous one. For the ones who would like to read it again, here is the link https://www.juvo.be/blog/kotlin-next-big-thing.

Time for business

You want to migrate your Java code to Kotlin code? Otherwise you wouldn’t be here, right? If not… I’m deeply sorry man but you’ve lost your way on the internet again. For everyone who is reading this blog because they want to migrate, step on the train and follow me on this journey!

Step 1:

STOP! (HAMMER TIME… sorry…) Stop with all the things you’re doing. Go home! Once you’re home and done with all the things you had to do, go to step 2. Migrating code isn’t something you start doing on a Friday evening 30 minutes before you leave work or with a bunch of colleagues who distract you with this-is-the-most-import-issue-I’ve-ever-seen ticket.

Step 2:

First step would be setting the right dependencies. You can easily add some dependencies without using them. In that way you can show everybody that you can run Kotlin and Java code next to each other. In this example I will be using Maven because there are a lot of  Gradle tutorials on the internet. Kotlin has an extensive standard library that can be used in your applications.

Configure the following dependency in the pom file:

<dependency>
     <groupId>org.jetbrains.kotlin</groupId>
     <artifactId>kotlin-stdlib</artifactId>
     <version>${kotlin.version}</version>
 </dependency>

If you're targeting JDK 7 or JDK 8, you can use extended versions of the Kotlin standard library which contain additional extension functions for APIs added in new JDK versions. Instead of kotlin-stdlib, use kotlin-stdlib-jdk7 or kotlin-stdlib-jdk8, depending on your JDK version (for Kotlin 1.1.x use kotlin-stdlib-jre7 and kotlin-stdlib-jre8 as the jdk counterparts were introduced in 1.2.0).

Ofcourse you want your tests also in Kotlin and not in Java, so you need to add the appropriate testing library.

<dependency>
     <groupId>org.jetbrains.kotlin</groupId>
     <artifactId>kotlin-test-junit</artifactId>
     <version>${kotlin.version}</version>
     <scope>test</scope>
 </dependency>

In our example we use Java 8 so we added the extended version of the Kotlin standard library, kotlin-stdlib-jre8

After that we need to configure our compiler plugin so that the compiler knows our target jvm and so on…

<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
	<groupId>org.jetbrains.kotlin</groupId>
	<version>${kotlin.version}</version>

	<configuration>
		<jvmTarget>1.8</jvmTarget>
	</configuration>
	<executions>
		<execution>
          	<id>compile</id>
               <goals> <goal>compile</goal> </goals>
			<configuration>
				<sourceDirs>
					<source>source/main/java</source>
				</sourceDirs>
			</configuration>
          </execution>

          <execution>
         		<id>test-compile</id>
			<goals> <goal>test-compile</goal> </goals>
		</execution>
	</executions>
</plugin>

Once you’ve changed your pom.xml like this you can fire it up and see if you get errors. When you get errors go back to the start and check every added line. It should not be so hard to find out what is wrong.

So that’s all! Step 2 was easy right ?!

Step 3: 

Now that we added Kotlin to our project we need to use it in our code. Start with migrating all the PoJo’s. Best way to do this is by creating a new Kotlin file and just copy paste your Java code in the new Kotlin file. Normally your IDE gives a popup with the question to convert the code. Of course you click “Yes”, we are developers, should I say more? After that your code should have the following formatting. This is java equivalent Kotlin code so don’t think your IDE fixes everything for you.

From this        

To this:                

     

Automatically we get the null check in our code, except this isn’t necessary in Kotlin code. You can also remove the Lombok annotation, which is the immutable version of Lombok’s @Data and replace your class name with “data class Boardgame”. These are just specific Kotlin features and are out of the scope of this blog. I’m sure you can find plenty of Kotlin vs Java features on the internet.

If you are done converting your first POJO to Kotlin code, do a Maven clean install and see if everything builds. This shouldn’t be a problem though. When everything is converted and your code still builds, it’s time to move to the next step. Hold on lads, we are almost there!

Step 4:

Time for some business logic refactoring ! You still know I said you need to be home or be chilled we you migrate code? This is why… refactoring business logic is some tricky business. Lots of projects are Spring based and I’m guessing yours is to. So when you want to combine Spring and Kotlin you’ll have to add another dependency called kotlin-reflect. After that you can do the same with your services like you did with your POJO’s. Don’t forget Kotlin classes are final and Spring doesn’t like that so you first need to “open” your class by adding “open” before “class classNameService”.  One more tip I can give is to triple check all your lambda’s. The convertor adds a lot of unnecessary code in lambda’s, which makes reading it a lot more difficult.  Further converting of your code is something you need to do on your own with the right Kotlin knowledge. Ps. stackoverflow.com is your guy.

Step 5:

The final step is the Spring boot configuration. Normally configuration looks like this:

@SpringBootApplication 
public class Application {  	
	public static void main(String[] args) { 
    SpringApplication.run(Application.class, args); 
	}  
}

After converting the config file to Kotlin, it looks like this.

@SpringBootApplication 
open class Application
fun main(args: Array<String>) { SpringApplication.run(Application::class.java,
*args) 
}

AAAAAND BOOOOOOOM THAT WAS IT!

Thank you all for reading and see you next time on probably another Kotlin blog!

Brent