Mix Java and Kotlin in Gradle Kotlin DSL with sourceSet

2 min read 30-09-2024
Mix Java and Kotlin in Gradle Kotlin DSL with sourceSet


Integrating Java and Kotlin in a single Gradle project can provide developers with the flexibility of using both languages, leveraging existing Java libraries while enjoying the modern features that Kotlin brings. In this article, we’ll walk through how to mix Java and Kotlin using the Gradle Kotlin DSL, specifically utilizing sourceSets.

Problem Scenario

You want to set up a Gradle project that uses both Java and Kotlin, managing the sources for each language efficiently using the Gradle Kotlin DSL. Here's the original code snippet that may have posed a challenge:

plugins {
    kotlin("jvm") version "1.5.31"
    `java`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib"))
}

tasks.withType<JavaCompile> {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Corrected and Explained Code

First, let’s improve the readability of the code snippet. We will add configurations for the source sets to ensure that both Java and Kotlin files are properly recognized by Gradle.

Here is the revised code:

plugins {
    kotlin("jvm") version "1.5.31"
    `java`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib"))
}

sourceSets {
    main {
        kotlin {
            srcDir("src/main/kotlin")
        }
        java {
            srcDir("src/main/java")
        }
    }
    test {
        kotlin {
            srcDir("src/test/kotlin")
        }
        java {
            srcDir("src/test/java")
        }
    }
}

tasks.withType<JavaCompile> {
    options.compilerArgs.addAll(listOf("-Xlint:unchecked", "-Xlint:deprecation"))
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Analysis and Explanation

  1. Plugins: The kotlin("jvm") plugin is necessary to work with Kotlin, while the java plugin enables Java support. Both languages can coexist seamlessly in one project when using the Kotlin DSL.

  2. Repositories: Declaring mavenCentral() allows us to fetch dependencies from the central Maven repository.

  3. Dependencies: The implementation directive pulls in the Kotlin standard library, which is crucial for any Kotlin project.

  4. SourceSets: This part is key for organizing source files. We explicitly define srcDir paths for both Kotlin and Java under the main and test source sets. This way, Gradle knows where to look for each language's source files, keeping them separate yet easy to manage.

  5. Compiler Options: The JavaCompile and KotlinCompile tasks are configured to set Java compiler arguments and Kotlin compiler options, respectively. Here, we specify the JVM target version for Kotlin to ensure compatibility with existing Java code.

Practical Example

Let's say you're developing a library that has existing Java code, and you want to enhance it with Kotlin features. By organizing your project with the above sourceSets, you can add new Kotlin functionality in src/main/kotlin, while maintaining the original Java code in src/main/java.

This approach allows you to refactor, enhance, or replace functionality incrementally without having to rewrite the entire codebase. It also encourages gradual adoption of Kotlin, allowing your team to learn and apply Kotlin features at their own pace.

Conclusion

Mixing Java and Kotlin in a single Gradle project using the Kotlin DSL and sourceSets is not only straightforward but also beneficial for developers wanting to leverage the best of both worlds. By following the examples provided above, you can ensure a clean and efficient project structure, making your codebase easier to manage and more maintainable.

Useful Resources

This comprehensive guide provides you with the necessary steps to efficiently mix Java and Kotlin in your projects, empowering you with the ability to innovate while maintaining legacy code.