javakotlingradlebuildsrc

How to use java plugin with buildSrc code


I'm trying to move the "make fat (aka. uber) jar" code I use from my root build.gradle.kts file into a file in the buildSrc directory. To that end I created a file buildSrc/src/main/kotlin/executableJar.kt:

import org.gradle.api.Project
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.register

fun Project.makeExecutableJar (name: String, main: String?, sset: SourceSet) : TaskProvider<Jar>
{
    return tasks.register<Jar>(name) {
        dependsOn(configurations.runtimeClasspath)
        archiveFileName.set("$name.jar")
        main?.let { manifest.attributes["Main-Class"] = it }
        duplicatesStrategy = DuplicatesStrategy.INCLUDE

        sset.allSource.forEach { println("==> Source: ${it.absolutePath}") }
        from(sset.output)

        from(sset.runtimeClasspath.filter {
            println("==> Include: ${it.name}")
            it.name.endsWith(".jar")}.map { zipTree(it) }
        )

    }
}

However, I get an "unresolved reference" in intJ for configurations.runtimeClasspath, which requires the java plugin. So I added a few lines to buildSrc/build.gradle.kts, which now looks like this:

plugins {
    `kotlin-dsl`
    java
}
repositories {
    mavenCentral()
    gradlePluginPortal()
}

But this does not solve the problem. How can I access the java plugin features for stuff in buildSrc? My best guess is that I need to include an explicit dependency { implementation(...) } for it, but, after searching maven and the gradle plugin portal, I can't determine an url/ID string for it.


Solution

  • configurations.runtimeClasspath is a generated Gradle Kotlin DSL accessor, and these are only available inside *.gradle.kts files.

    Instead you'll have to access the configuration by the name, using ConfigurationContainer.getByName().

    Conveniently, JavaPlugin provides the name of the runtimeClasspath Configuration, so it can be imported and used directly (rather than using a 'magic' string).

    // import JavaPlugin
    import org.gradle.api.plugins.JavaPlugin
    
    // (existing imports)
    // import ...
    
    fun Project.makeExecutableJar (name: String, main: String?, sset: SourceSet) : TaskProvider<Jar> {
        // access the runtimeClasspath configuration
        val runtimeClasspathConfiguration = configurations.named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
        
        return tasks.register<Jar>(name) {
            dependsOn(runtimeClasspathConfiguration )
            // ...
        }
    }