DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Data
  4. Migrating From Lombok to Kotlin

Migrating From Lombok to Kotlin

Shorter code should never be the goal. It’s the readability of the code that matters.

Erik Pragt user avatar by
Erik Pragt
·
Mar. 19, 19 · Tutorial
Like (32)
Save
Tweet
Share
40.31K Views

Join the DZone community and get the full member experience.

Join For Free

As a Java developer, one of the most commom complaints about working in Java is the verbosity of the language. One of the main areas where this verbosity really shows up is in the area of data classes. Data classes, or tuples or records, one day might end up in the Java language, but until that day, whenever one creates a REST DTO, JPA Entity, Domain class, or anything like this, Java's verbosity shows up. In this article, I'll describe how to migrate from Lombok to Kotlin and some of benefits that come from this migration.

// 40 Lines of Java code for a class with 2 properties
import java.time.LocalDate;
import java.util.Objects;

public class Person {
    private String name;
    private LocalDate dateOfBirth;

    public Person(String name, LocalDate dateOfBirth) {
        this.name = name;
        this.dateOfBirth = dateOfBirth;
    }

    public String getName() {
        return name;
    }

    public LocalDate getDateOfBirth() {
        return dateOfBirth;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name) &&
                Objects.equals(dateOfBirth, person.dateOfBirth);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, dateOfBirth);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", dateOfBirth=" + dateOfBirth +
                '}';
    }
}


To effectively use Data classes, you often end up with a series of properties; a constructor; a series of getters; perhaps, an equals; hashcode and a toString method; and, in some alternative, corporate world, an evil setter here or there. Since this is such a common issue, several solutions have been created — Lombok being the most well known, but alternatives such as AutoValue and Immutables also exist.

However, in this blog post, I’m going to focus on moving away from Lombok to Kotlin, since it’s a great way to get started with Kotlin, it’s a low risk and easy to understand, plus Kotlin provides many benefits over Java, thus migrating to Kotlin Data classes is a great start to start adopting Kotlin in the rest of your codebase.

Small disclaimer: while this blog post focuses on the migration to Kotlin, I in no way think that Lombok is bad. It’s a great tool and provides a lot of benefits for standard Java code. This is merely a demonstration on how to use Kotlin in places where Lombok is currently used.

What Is Lombok?

For those unfamiliar with Lombok, Lombok is a generator library that removes the verbosity of Java code. For example, in the above class, using the Lombok library, the code would look like this:

import java.time.LocalDate;
import lombok.Value;

@Value
public class Person {
private String name;
private LocalDate dateOfBirth;
}


This is much nicer, right? The @Value annotation, in this case, creates the class final, a constructor with the two parameters, getters, equals, hashcode, and toString.

What Is Kotlin?

While the above is a huge improvement over the original code, this post is focusing on the migration to Kotlin. As such, our initial example can be rewritten in Kotlin with the following code:

data class Person(val name: String, val dateOfBirth: LocalDate)


This code does the same as the Lombok code, creating the constructor, a toString, equals/hashcode, etc.

While this is even shorter, shorter code should never be the goal. It’s the readability of the code that matters. In this case, one could argue that both are equally readable, and I’d tend to agree with that. However, by introducing the Kotlin version, the equal readability of both is a great reason to move to Kotlin. The above code is 100 percent interoperable with the rest of the Java codebase. It, therefore, shouldn’t be a hard sell to introduce Kotlin into the code.

Lombok to Kotlin Migration Guide

While the above was just a small example, the following table will show a complete overview of how to move to Kotlin data classes.

Feature Lombok Kotlin Note
Final local references val val val is a Kotlin keyword
Reassignable local references var var var is a Kotlin keyword
Non-nullable references @NonNull No keyword needed In Kotlin, types are nonnullable by default, and need to be explicitly declared nullable with a question mark, ie String?.
Automatic Resource Management (ARM) @Cleanup Closeable.use For example:
val result = FileInputStream("input.txt").use { input -> //Process input
}
Create getters and setters @Getter/@Setter Part of data classes by declaring properties as var in data classes For example:
data class Person(var name: String)
Creates a getter and setter of name on Person.
Create a toString @ToString Part of data classes For example:
data class Person(var name: String)
Creates an automatic toString on Person.
Create a equals and hashcode method @EqualsAndHashCode Part of data classes For example:
data class Person(val name: String)
Creates an automatic equals and toString on Person.
Create a constructor without any arguments @NoArgsConstructor Part of data classes by giving all arguments a default value or by introducing a secondary constructor For example:
data class Person(val name: String = “”)
Assigns a default value to name and creates a default no-arg constructor.

Alternatively, create a secondary constructor:
data class Person(var name: String) {   constructor() : this(“”)
}
Create a constructor with parameters equal to the number of properties defined @RequiredArgsConstructor and @AllArgsConstructor
Part of data classes For example:
data class Person(val name: String)

Automatically creates a constructor for all parameters.
Create a mutable data class @Data Part of data classes by using ‘var’ in field declarations For example:
data class Person(var name: String)

Automatically creates the toString, hashCode, equals, etc.
Create an immutable data class @Value Part of data classes by using ‘val’ in field declarations For example:
data class Person(var name: String)
Creates an automatic toString on Person.
Object creation using named properties @Builder Named arguments in Kotlin Person(name = “Sergey”, age = 25)
Convert checked exceptions into unchecked exceptions @SneakyThrows All checked exceptions called from Kotlin code are unchecked. Kotlin methods declared with @Throws, when called from Java, still can throw a checked exception.
Synchronised methods using locks. @Synchronized Kotlin withLock method. It’s not completely the same, but it’s close. A better alternative is to look at Kotlin coroutines someLock.withLock {    sharedResource.operation()}
Lazy property initialization. @Getter(lazy=true) Delegated properties `by lazy`
Automatic logger @Log No built-in alternative... ...but a marker interface would make this easy to implement.

As you can see in the table above, most features of Lombok are available in Kolin. However, what is so great about Lombok is it's flexibility. For example, it’s easy to add a toString method to a class without adding an Equals/HashCode method. In Kotlin, this is not easily done.

In practice, the need for just a toString method is, in my experience, not something that happens often, but it’s good to know that Lombok is a bit more flexible in this regard than Kotlin.

How to Add Kotlin Support to a Project

To start the migration, you’ll need to add Kotlin support to your project. You can easily do this by adding Kotlin support to your Maven project, or by adding Kotlin support to your Gradle project.

Using Kotlin and Lombok at the same time is not a great idea, since the compilation of Kotlin source code happens in the same phase as the Lombok code generation. As a result, the Kotlin code cannot use the Lombok-generated methods. You can work around this by putting the code into a separate project, but my recommendation would be to either migrate completely in one go, or, something that we did, you can deLombok the project and slowly migrate to Kotlin. Whichever approach you take depends mostly on your project size, but for us, the easiest was to deLombok the project and convert it to Kotlin.

Conclusion

I hope the above guide introduced Kotlin into your project. It should be a safe and readable conversion, which provides a basis for introducing more advanced Kotlin features into the project at a later stage, such as more idiomatic Kotlin code, coroutines, Kotlin typesafe DSLs, and much more.

Happy coding!

Kotlin (programming language) Data (computing) Java (programming language) IT Strings Data Types

Published at DZone with permission of Erik Pragt. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Reliability Is Slowing You Down
  • Cloud Performance Engineering
  • What Is API-First?
  • Fargate vs. Lambda: The Battle of the Future

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: